在 R 中基于二进制指标动态创建变量

Dynamically Create Variables Based on Binary Indicators in R

我有这样的用户级数据:

ID  V1 V2 V3 V4
001 1  0  1  0
002 0  1  0  1
003 0  0  0  0
004 1  1  1  0

在上面的示例中,我想要一个优雅的解决方案(可能使用 tidyr)来动态重构它以显示为:

ID  Num_Vars Var1 Var2 Var3
001 2        V1   V3   NA
002 2        V2   V4   NA
003 0        NA   NA   NA
004 3        V1   V2   V3

注意这个例子是简化的,实际上有很多变数。关键是要有代码来检测应该创建多少变量,基于为任何用户填充的 Var1-VarX 中 1 的最大数量。

这感觉像是一些相当标准的重塑:转换为长,按组操作,转换回宽:

df %>%
    gather(key = var, value = value, -ID) %>%
    group_by(ID) %>%
    filter(value != 0) %>%
    mutate(Num_Vars = n(),
           Var_Label = paste0("Var", 1:n())) %>%
    spread(key = Var_Label, value = var) %>%
    select(-value) %>%
    full_join(distinct(df, ID))
# Source: local data frame [4 x 5]
# Groups: ID [?]
# 
#      ID Num_Vars  Var1  Var2  Var3
#   <int>    <int> <chr> <chr> <chr>
# 1     1        2    V1    V3  <NA>
# 2     2        2    V2    V4  <NA>
# 3     4        3    V1    V2    V3
# 4     3       NA  <NA>  <NA>  <NA>

使用与 dput() 可重复共享的数据:

df = structure(list(ID = 1:4, V1 = c(1L, 0L, 0L, 1L), V2 = c(0L, 1L, 
0L, 1L), V3 = c(1L, 0L, 0L, 1L), V4 = c(0L, 1L, 0L, 0L)), .Names = c("ID", 
"V1", "V2", "V3", "V4"), class = "data.frame", row.names = c(NA, 
-4L))

我们可以使用 melt/dcast 来自 data.table

library(data.table)
dcast(melt(setDT(df), id.var = "ID")[, Num_vars := sum(value), 
   ID][value!=0][df[, "ID", with = FALSE], on = "ID"], 
   ID + Num_vars ~ paste0("Var", rowid(ID)), value.var = "variable")
#    ID Num_vars Var1 Var2 Var3
#1:  1        2   V1   V3   NA
#2:  2        2   V2   V4   NA
#3:  3       NA   NA   NA   NA
#4:  4        3   V1   V2   V3