0

我有一个如下所示的数据结构:

 groupA1    groupA2    groupB1    groupB2    date        text
     0         1          1          1      2013-01-01   the dog

对于每个groupB变量,我想为值为 1 的每一列列出一行。我需要将所有 1 的组合groupAgroupB其中 1 的位置列在一行中,然后还将日期和文本添加到每个组合中该行中的列。

转换后的数据将显示为:

var_groupB  var_groupA  date         text
 groupB1    groupA2     2013-01-01    the dog
 groupB2    groupA2     2013-01-01    the dog

我尝试了 和 的组合,meltddply总是没有我需要的变量之一。

我尝试过的一件事是,但后来我丢失了有关和melt(x, id.vars=c("text", "date"))之间关系的所有信息。groupAgroupB

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

4

2 回答 2

5

您可以melt两次,每组一次:

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")

这将为 A 和 B 的每种组合提供一行:

        date    text var_groupA val_groupA var_groupB val_groupB
1 2013-01-01 the dog    groupA1          0    groupB1          1
2 2013-01-01 the dog    groupA2          1    groupB1          1
3 2013-01-01 the dog    groupA1          0    groupB2          1
4 2013-01-01 the dog    groupA2          1    groupB2          1

然后您可以对其进行子集化并删除值列:

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

这给了你你想要的:

  var_groupA var_groupB       date    text
2    groupA2    groupB1 2013-01-01 the dog
4    groupA2    groupB2 2013-01-01 the dog

当然,如果您的数据集比您的示例更复杂,您可以通过以更自动化的方式进行融合和子集化来使该解决方案更优雅 - 例如,检测组列并自动填充, , measure.vars,也许是任意数量的组。variable.namevalue.name

于 2014-06-03T22:22:40.863 回答
2

前 2 条语句将前 4 列中的每个 0 替换为 "",并将每个 1 替换为列名dd2。接下来的两个语句使用结果为 为每一行生成groupA和的所有组合。最后 ,对于那些没有条目的行:groupBexpand.griddd3subset""

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
于 2014-06-03T23:05:26.457 回答