R 数据的这种重塑是可能的吗?

R 数据的这种重塑是可能的吗?,r,melt,R,Melt,我的数据结构如下所示: groupA1 groupA2 groupB1 groupB2 date text 0 1 1 1 2013-01-01 the dog 对于每个groupB变量,我想为每个值为1的列列出一行。 我需要列出groupA和groupB的所有组合,其中1出现在一行中,但还要将日期和文本作为该行的列添加到每个组合中 转换后的数据将显示为: var_groupB

我的数据结构如下所示:

 groupA1    groupA2    groupB1    groupB2    date        text
     0         1          1          1      2013-01-01   the dog
对于每个
groupB
变量,我想为每个值为1的列列出一行。 我需要列出
groupA
groupB
的所有组合,其中1出现在一行中,但还要将日期和文本作为该行的列添加到每个组合中

转换后的数据将显示为:

var_groupB  var_groupA  date         text
 groupB1    groupA2     2013-01-01    the dog
 groupB2    groupA2     2013-01-01    the dog
我尝试了
melt
ddply
的组合,但总是没有我需要的变量

我尝试过的一件事是
melt(x,id.vars=c(“text”,“date”))
,但随后我丢失了有关
groupA
groupB
之间关系的所有信息


我可以使用一个凌乱的循环来完成这项工作,但不确定是否存在我不知道的
重塑
实用程序,并且可以完成这项工作。

您可以
熔化
两次,每组一次:

y <- melt(x, measure.vars=c("groupA1", "groupA2"),
          variable.name="var_groupA", value.name="val_groupA")
y <- melt(y, measure.vars=c("groupB1", "groupB2"),
          variable.name="var_groupB", value.name="val_groupB")
然后您可以将其子集并删除值列:

y <- y[y$val_groupA == 1 & y$val_groupB==1, ]
y <- y[, c("var_groupA", "var_groupB", "date", "text")]

当然,如果您的数据集比示例中的数据集更复杂,您可以通过以更自动化的方式进行融合和子集设置,使此解决方案更优雅——例如,检测组列并自动填充
measure.vars
variable.name
,和
value.name
,可能适用于任意数量的组。

前2条语句将前4列中的每个0替换为“”,将每个1替换为给出
dd2
的列名。接下来的两条语句使用
expand.grid
为每一行生成
groupA
groupB
的所有组合,结果为
dd3
。最后,将
子集
添加到没有
项的行中。
项:

newvals <- function(nm) ifelse(dd[[nm]] == 0, "", nm)
dd2 <- replace(dd, 1:4, lapply(names(dd)[1:4], newvals))

combo <- function(x) data.frame(expand.grid(groupA=c(x[1:2]), groupB=c(x[3:4])), 
             x$date, x$text)
dd3 <- do.call("rbind", by(dd2, 1:nrow(dd2), combo)) 

subset(dd3, groupA != "" & groupB != "")

您可能会在“data.table”包中找到一些帮助,但如果您问我的话,这看起来像是个难题。
  var_groupA var_groupB       date    text
2    groupA2    groupB1 2013-01-01 the dog
4    groupA2    groupB2 2013-01-01 the dog
newvals <- function(nm) ifelse(dd[[nm]] == 0, "", nm)
dd2 <- replace(dd, 1:4, lapply(names(dd)[1:4], newvals))

combo <- function(x) data.frame(expand.grid(groupA=c(x[1:2]), groupB=c(x[3:4])), 
             x$date, x$text)
dd3 <- do.call("rbind", by(dd2, 1:nrow(dd2), combo)) 

subset(dd3, groupA != "" & groupB != "")
     groupA  groupB     x.date  x.text
1.2 groupA2 groupB1 2013-01-01 the dog
1.4 groupA2 groupB2 2013-01-01 the dog