如何根据其他变量的分组进行行求和?

4
以下是示例数据:
df <- data.frame("ID1" = c("A","A","B","C"), 
            "Wt1" = c(0.8,0.6,0.4,0.5),
            "ID2" = c("B","A","C","B"),
            "Wt2" = c(0.1,0.4,0.5,0.5),
            "ID3" = c("C",NA,"C",NA), 
            "Wt3" = c(0.1,NA,0.1,NA))

我将会尝试翻译您的内容。需要在数据框中创建一列(投票),该列基于ID1、ID2、ID3组的wt的argmax。例如,在示例数据的第3行中,"B"的权重总和为0.4,"C"的权重总和为0.6,因此投票="C"。
结果将类似于:
  ID1 Wt1 ID2 Wt2  ID3 Wt3 vote
1   A 0.8   B 0.1    C 0.1    A
2   A 0.6   A 0.4 <NA>  NA    A
3   B 0.4   C 0.5    C 0.1    C
4   C 0.5   B 0.5 <NA>  NA    C

在出现平局的情况下(例如示例中的第4行),只需选择任意一个ID值。有人可以提供解决方案吗?

3
df[is.na(df)] <- -Inf;df$vote <- df[c(T,F)][cbind(1:nrow(df), max.col(df[c(F,T)]))] 可能有效。你会收到因为因子变量而产生的警告,但对于这个示例来说它是有效的。如果需要进一步解释我可以说明。 该代码意思为将数据框df中的空值设为负无穷,并根据行中最大的非空值所在的列索引,在df的vote列中填充相应的值。虽然该代码可能会触发有关因子变量的警告,但对于提供的示例数据而言,它是可行的。如果需要更详细的解释,请让我知道。 - Pierre L
谢谢!@PierreLafortune。解决方案有效且非常简洁...你能进一步解释吗? - Wei Wang
您没有为相同值指定决胜规则。 - Pierre L
1个回答

1

首先,操作这种格式的表格非常困难。我担心你会在后面遇到麻烦。

建议重新格式化表格,以便我们可以轻松地检索信息。

给每个观察分配一个ID。

df$obs <- 1:nrow(df)

然后将它们以长格式排列。
  df1 <- do.call("rbind",lapply(seq(1,6,2),function(x) {df <- df[,c(x: (x+1),7)]; 
colnames(df) <- c("ID","Wt","obs"); df}))

由于我在使用data.frame时的能力有限,因此我转而使用data.table包。

dt <- as.data.table(df1)

我们按照观测和ID对投票数量进行求和。
dt[,total:=sum(Wt,na.rm=TRUE),.(obs,ID)]

然后,检索信息非常容易。
dt[,vote:=.SD[which.max(total)],obs]

#dt
#    ID  Wt obs total vote
# 1:  A 0.8   1   0.8    A
# 2:  A 0.6   2   1.0    A
# 3:  B 0.4   3   0.4    C
# 4:  C 0.5   4   0.5    C
# 5:  B 0.1   1   0.1    A
# 6:  A 0.4   2   1.0    A
# 7:  C 0.5   3   0.6    C
# 8:  B 0.5   4   0.5    C
# 9:  C 0.1   1   0.1    A
# 10: NA  NA   2   0.0    A
# 11:  C 0.1   3   0.6    C
# 12: NA  NA   4   0.0    C

谢谢!@DJJ 我意识到添加行标签并转换为长格式是一个非常好的想法。我可以通过obs将原始表格左连接到结果表格。 - Wei Wang

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