2015-01-15 119 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])])