根据另一个变量添加数据框中的行

3

我正在尝试实现一种有条件的rowSums

我有一个数据框,其中包含四列包含1和0,另外一个变量表示应该添加哪些列以计算行总数。

例如:

df <- matrix(rbinom(40, 1, 0.5), ncol = 4)
df <- as.data.frame.matrix(df)
df$group <- sample(c('12', '123', '1234'), 10, replace = T)

如果组是12,则应添加列V1:V2,如果是123,则应添加列V1:V3,如果是1234,则应添加列V1:V4。
我尝试了一种劳动密集型的方法:
df$total12 <- rowSums(df[,c('V1', 'V2')])
df$total123 <- rowSums(df[,c('V1', 'V2', 'V3')])
df$total1234 <- rowSums(df[,c('V1', 'V2', 'V3', 'V4')])
df$total <- ifelse(df$group == '12', df$total12,
                   ifelse(df$group == '123', df$total123, df$total1234))

有没有更简单的方法来完成这个任务?

理想情况下,非连续值也可以工作 - 但是数据可以被安排成只需要连续值。 - Dan Lewer
2个回答

1
这里有一个选项。我们通过拆分“group”创建行/列索引,基于索引提取“df”的值,并通过行索引进行分组得到sum
lst <- strsplit(df$group, "")
i1 <- cbind(rep(seq_len(nrow(df)), lengths(lst)), as.integer(unlist(lst)))
df$total <- ave(df[-5][i1], i1[,1], FUN = sum)

1
非常好的答案 - 謝謝 @akrun。由於某些原因,ave 部分對我不起作用,我不得不用 sapply(split(df[-5][i1], f = i1[,1]), sum) 來替換它。 - Dan Lewer

1

这里是另一种使用 switch 函数的选项。相比于一系列嵌套的 ifelse 语句,这种方式更易读且更易扩展。

df$total<-sapply(1:length(df$group), function(i){switch(df$group[i], 
            "12"=rowSums(df[i, c('V1', 'V2')]),
            "123"=rowSums(df[i, c('V1', 'V2', 'V3')]),
            "1234"=rowSums(df[i, c('V1', 'V2', 'V3', 'V4')]))})

基本上,循环遍历df $ group的元素并选择正确的公式。 如果您的数据集不太长,则性能应该是可接受的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接