在 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
我有这样的用户级数据:
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