我的问题类似于其他问题,例如:Sum of rows based on column-value
在R中使用data.table
,如果我想根据另一列中的唯一值对列中的值求和,我可以执行以下操作:
mre = data.table(
ref=rep(LETTERS[1:5],3),
qual=c('B','C','D','E','A','C','D','E','A','B','D','E','A','B','C'),
score=10:24
)
mre[,team_score:=sum(score),by=ref]
或者:
mre[,team_val:=sum(score),by=qual]
但我怎样才能同时做到这两件事呢?也就是说,添加mre[,score]
中mre[,ref]
或mre[,qual]
等于五个唯一值(A到E)之一的所有元素。因此,对于A,新列中的元素将是分数中所有行的总和,其中A出现在mre[,ref]
或mre[,qual]
(1,5,6,9,11,13)中。
我能做到:
mre[ref=="A"|qual=="A",team_val:=sum(score)]
但这非常低效。当然有更好/更聪明的data.table
方式来做到这一点?
编辑:澄清所需的输出,更好的例子
我可以这样做,而不是创建一个新列并通过引用计算总和,这会导致涉及ref
和qual
列中多个值的并发症,我可以这样做:
test=
merge(setkey(setnames(mre[,sum(score),by=ref],"ref","test_val"),test_val),
setkey(setnames(mre[,sum(score),by=qual],"qual","test_val"),test_val),
all=T)[,team_val:=rowSums(.SD,na.rm=T),.SDcols=c("V1.x","V1.y")]
产生:
> test
test_val V1.x V1.y team_val
1: A 45 54 99
2: B 48 52 100
3: C 51 50 101
4: D 54 48 102
5: E 57 51 108
我希望以一种不需要合并的方式来做这件事。我只需要team_val
列,我立即在一个乘法表达式中使用另一个data.table
的列(所以我可以这样做:
team_val =
merge(setkey(setnames(mre[,sum(score),by=ref],"ref","test_val"),test_val),
setkey(setnames(mre[,sum(score),by=qual],"qual","test_val"),test_val),
all=T)[,rowSums(.SD,na.rm=T),.SDcols=c("V1.x","V1.y")]
得到:
> team_val
[1] 99 100 101 102 108
但仍需要合并)。我正在努力加入链接(即Section 2b)。
答案 0 :(得分:1)
我认为这就是你想要的......
sapply(unique(c(mre$ref, mre$qual)), function(x) sum(mre$score[mre$ref == x | mre$qual == x]))
A B C D E
99 100 101 102 108
使用1.5m行的data.frame /表,只需2秒钟。
如果你能明确指定等级,它会快一点。
sapply(LETTERS[1:5], function(x) sum(mre$score[mre$ref == x | mre$qual == x]))
1.5米行的时间不到1.5秒。