R数据表条件聚合

8

我面临着一个(我认为)非常棘手的问题,涉及到data.table的聚合。

我有以下的data.table

structure(list(id1 = c("a", "a", "a", "b", "b", "c", "c"), id2 = c("x", 
"y", "z", "x", "u", "y", "z"), val = c(2, 1, 2, 1, 3, 4, 3)), .Names = c("id1", 
"id2", "val"), row.names = c(NA, -7L), class = c("data.table", 
"data.frame"), .internal.selfref = <pointer: 0x1f66a78>)

我想在基于第二列 id2 的数据上创建条件聚合,聚合的方式是仅包括具有给定 id2 元素中至少一个元素的 id1 组。我将通过一个示例来说明我的意思。
对于 x 的条件聚合(第一行第二列),应包括 val 值 2、1、2,以及来自 id1 = bval 值 1、3,因为它们存在 id2=x,但没有来自 id1=c 的值,结果为 2 + 1 + 2 + 1 + 3 = 9。我希望将这个 9 作为第四列出现在每一行中,其中 id2 = x
同样地,我希望对所有的 id2 值进行此操作。因此最终输出将是:
    id1 id2 val c.sum
1:   a   x   2     9
2:   a   y   1    12
3:   a   z   2    12
4:   b   x   1     9
5:   b   u   3     4
6:   c   y   4    12
7:   c   z   3    14

这在R的data.table中是否可能?或者其他的包/方法呢? 谢谢。

2
我对预期结果感到困惑。如果id2包含z,您会期望c.cum中有12。我是否漏掉了什么? - jazzurro
一切都很好。现在你得到了答案。 :) - jazzurro
2
如果这是一个打字错误,为什么不将其更改为正确的值呢? - Rich Scriven
2个回答

5

假设 d 是您的输入结构:

library(data.table)

d[,c.sum:=sum(d$val[d$id1 %in% id1]),by=id2][]

如何工作:by=id2 将输入数据表格 d 按照 id2 进行分组;d$id1 %in% id1 选择在考虑组的 id1 匹配的 d 行;sum(d$val[...]) 对这些行的值进行求和;最后,c.sum:=sum(...)d 添加了一个名为 c.sum 的列。结尾的 [] 仅用于打印目的。

输出为:

#    id1 id2 val c.sum
# 1:   a   x   2     9
# 2:   a   y   1    12
# 3:   a   z   2    12
# 4:   b   x   1     9
# 5:   b   u   3     4
# 6:   c   y   4    12
# 7:   c   z   3    12

我获取了16个值的所有数值。 - IRTFM
不知道为什么你在末尾加上了 []。除了打印目的外,这是不必要的。 - thelatemail
1
@thelatemail,我当时考虑的就是打印目的)。 - Marat Talipov
我会将它删除 - 它并不是实际分配变量的代码的一部分,可能会让人感到困惑。我不希望看到人们学习在 data.table 代码之后不必要地包含 [] - thelatemail
我收到一个错误,指出“未使用的参数(by = id2)”。 - Jthorpe
显示剩余7条评论

2

这种方法有些蛮力,但它应该可以工作(假设data是您的数据结构):

id1_sums <- tapply(data$val,data$id1,sum)  
for(id in unique(data$id2))
    data$c.sum[data$id2  == id] <- sum(
            id1_sums[which(names(id1_sums) %in% data$id1[data$id2 == id])])

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