2012-05-24 11 views
8

私は、(私の知る限り)まだ実装されていない、グループ別のdata.tableでの参照による代案の最良の代替案を探しています。 data.table例を用いて、Iは、Fを含む、新しい列Zを追加するdata.table DT [、x:= f(y)、by = z]としてグループ化された代入の効率的な代替?

DT = data.table(x=rep(c("a","b","c"),each=3), y=c(1,3,6), v=1:9) 
    x y v 
[1,] a 1 1 
[2,] a 3 2 
[3,] a 6 3 
[4,] b 1 4 
[5,] b 3 5 
[6,] b 6 6 
[7,] c 1 7 
[8,] c 3 8 
[9,] c 6 9 

(yは、V)は、xの値によってグループ化された(+ F(Y、V)=平均値(y)を取ることができv)。私は

DT[,mean(y)+v,by=x] 
     x  V1 
[1,] a 4.333333 
[2,] a 5.333333 
[3,] a 6.333333 
[4,] b 7.333333 
[5,] b 8.333333 
[6,] b 9.333333 
[7,] c 10.333333 
[8,] c 11.333333 
[9,] c 12.333333 

のようにこの計算の結果を印刷または保存したくないことに注意してくださいではなく、私はDTに結果を追加したい:

 x y v  V1 
[1,] a 1 1 4.333333 
[2,] a 3 2 5.333333 
[3,] a 6 3 6.333333 
[4,] b 1 4 7.333333 
[5,] b 3 5 8.333333 
[6,] b 6 6 9.333333 
[7,] c 1 7 10.333333 
[8,] c 3 8 11.333333 
[9,] c 6 9 12.333333 

私data.tableは262メガバイトを持っています、このよう

DT <- DT[,transform(.SD,mean(y)+v),by=x] 

ことは、私はメモリ内に二度DTに合うことができないので(コピー操作によって暗示されている、私は思う)、オプションではありません。事実、私はこの操作が完了したことを見たことがない。

data.tableにDT [、z:= mean(y)+ v、by = x]が付くまでどの代替手段がありますか?

私はちょうどDT [newDT]について読んでいます。ここで何が間違っていますか?その後、

newDT <- DT[,mean(y)+v,by=x] 
     x  V1 
[1,] a 4.333333 
[2,] a 5.333333 
[3,] a 6.333333 
[4,] b 7.333333 
[5,] b 8.333333 
[6,] b 9.333333 
[7,] c 10.333333 
[8,] c 11.333333 
[9,] c 12.333333 

(なんとかメモリが賢明である。):

> DT[newDT] 
setkey(DT,x) 
setkey(newDT,x) 
x y v  V1 
a 1 1 4.333333 
a 3 2 4.333333 
a 6 3 4.333333 
a 1 1 5.333333 
a 3 2 5.333333 
a 6 3 5.333333 
a 1 1 6.333333 
a 3 2 6.333333 
a 6 3 6.333333 
b 1 4 7.333333 
b 3 5 7.333333 
b 6 6 7.333333 
b 1 4 8.333333 
b 3 5 8.333333 
b 6 6 8.333333 
b 1 4 9.333333 
b 3 5 9.333333 
b 6 6 9.333333 
c 1 7 10.333333 
c 3 8 10.333333 
c 6 9 10.333333 
c 1 7 11.333333 
c 3 8 11.333333 
c 6 9 11.333333 
c 1 7 12.333333 
c 3 8 12.333333 
c 6 9 12.333333 

が、それは私が欲しいものではありません。ここで間違いは何ですか?

+0

+1グレート質問:

だから、あなたが2番目のキーを必要と採掘するのは非常に似ていることにあなたの方法を行うには! –

答えて

4
DT[, xm := ave(y, x, FUN=mean) + v] 
+0

+1非常に良い解決策、私はあなたのものが動作しないと思ったので、私は長い1つを書いただけです。 'ave'をもう一度見て、DT [、xm:= ave(y、x、FUN = mean)+ v]'を意味すると思います。それは魅力のように機能し、最も効率的になる可能性があります。 –

+1

+1 '' by 'は 'ave'よりも速いので、' 'by:group by" "が終了するまで、これはもっと効率的です(醜いですが):DT [、xm:= DT [、mean( y)+ v、by = x] [[2]]] ' –

+0

ありがとう。私は 'ave'が存在することさえ知りませんでした。グループで ':='を楽しみにしています! –

3

私は次の操作を行います。したがって、基本的

DT[, list(fvy = mean(y)), by="x"][DT][, fvy := fvy + v] 

が、私は二つの部分にそれを分割:まず、私は yの平均値を計算し、DTにそれを追加し、その後、私は vを追加平均は yである。メモリ的にはこれが本当に助けになるか分かりませんが、作者が見て、私たちに知らせる良いチャンスがあります;-)

あなたの質問について、それがうまくいかない理由は基本的に、マージする2つのデータテーブル:DTnewDT。両方のデータテーブルには、すべてのキーが3回あります。だから、あなたがそれらをマージすると、すべての組み合わせが結果になるので、9 a、b、cのdata.tableを取得するのです。

newDT <- DT[,list(fvy=mean(y)+v, v),by=x] 
setkey(newDT, x, v) 
setkey(DT, x, v) 
DT[newDT] 
     x v y  fvy 
[1,] a 1 1 4.333333 
[2,] a 2 3 5.333333 
[3,] a 3 6 6.333333 
[4,] b 4 1 7.333333 
[5,] b 5 3 8.333333 
[6,] b 6 6 9.333333 
[7,] c 7 1 10.333333 
[8,] c 8 3 11.333333 
[9,] c 9 6 12.333333 
+1

+1努力のために。私たちは実際にグループによって ':='を必要とします。そうではありません。ほぼそこに。 '' DT [、newx:= colA + 2] [、newy:= newx * 2] [、newz:= colA + newx + newy] ... ' –

+2

しかし私はコンパイル'誰かがそれを望んでいる場合に備えて、複数の ':=' by by'をまだ実行しません。それは、次のバージョンでは 'by = 'によって':= 'になるだけです。将来のバージョンは 'DT {、{newx:= colB + 2; newy:= newx + colC}、by = colA]' –

+0

thanks christoph_Jです。その重要なことは完全に意味をなす。 –

関連する問題