2015-01-15 87 views
7

我面对(我认为)是data.table 一个艰难的问题汇总我下面data.table[R 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>) 

我想创建条件骨料val列基于第二列id2。聚合完成的方式是只包含id1组,其中至少有一个元素来自给定的元素。我将通过一个例子来展示我的意思。

有条件骨料x(第一行第二列)将包括id1 = aval值2,1,2和val值= 1,3从id1 = b因为id2=x存在他们,但没有从值id1=c,导致2 + 1 + 2 + 1 + 3 = 9的值。我想把9作为第012列中的第4列,其中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

+0

错字,我的意思是12. – broccoli

+0

这很好。现在你得到了答案。 :) – jazzurro

回答

3

鉴于d是你的输入结构:

library(data.table) 

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

工作原理:by=id2组输入数据表d通过id2; d$id1 %in% id1d中选择其行id1id1匹配的行; sum(d$val[...])取得来自这些行的值的总和;最后,c.sum:=sum(...)将列添加到d。结束[]仅用于打印目的。

输出是:

# 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 
+0

我得到的所有值都是16. –

+0

@BondedDust:它可能与'data.table'版本有关吗?我使用data.table_1.9.4。 –

+0

这必须要求加载一个包。我加载了'data.table',但上面的代码对我不起作用。您可以添加此解决方案运行所需的任何'library()'语句吗? – Jthorpe

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