data.tableで:=演算子を使用する必要があるのはいつですか?


88

data.tableオブジェクトに:=演算子が追加されました。この演算子が他のすべての代入演算子と異なる点は何ですか?また、その用途は何ですか、それはどれくらい速いですか、そしてそれはいつ避けるべきですか?

回答:


94

これは、10分が1秒に短縮された例です(ホームページのNEWSから)。これは、にサブ割り当てするようなものですが、data.frame毎回テーブル全体をコピーするわけではありません。

m = matrix(1,nrow=100000,ncol=100)
DF = as.data.frame(m)
DT = as.data.table(m)

system.time(for (i in 1:1000) DF[i,1] <- i)
     user  system elapsed 
  287.062 302.627 591.984 

system.time(for (i in 1:1000) DT[i,V1:=i])
     user  system elapsed 
    1.148   0.000   1.158     ( 511 times faster )

パッティング:=jより多くのイディオムを可能にするように:

DT["a",done:=TRUE]   # binary search for group 'a' and set a flag
DT[,newcol:=42]      # add a new column by reference (no copy of existing data)
DT[,col:=NULL]       # remove a column by reference

および:

DT[,newcol:=sum(v),by=group]  # like a fast transform() by group

避ける理由が思いつかない:=!それ以外は、forループ内。:=内部DT[...]に表示されるため、[.data.tableメソッドのオーバーヘッドが小さくなります。例えば、S3の派遣とのような引数の有無と種類をチェックibynomatch内部のためなどだから、forループは、低オーバーヘッドの直接のバージョンがある:=と呼ばれますset?set詳細と例については、を参照してください。setincludeの欠点は、i行番号でなければならず(バイナリ検索なし)、それをと組み合わせることができないことbyです。これらの制限をset行うことにより、オーバーヘッドを劇的に減らすことができます。

system.time(for (i in 1:1000) set(DT,i,"V1",i))
     user  system elapsed 
    0.016   0.000   0.018

26
このパッケージを開発していただきありがとうございます。このパッケージを使用するために、コードの多くを改訂するつもりだと感じています。
イテレータ2011

1
チャットで私は、自己に頼まれた(明らかにされた/答え尋ねる奨励を) -その質問があり、ここで
マット・Dowle

4
@MatthewDowle:=を使用せず、代わりにset()を使用する場合の説明を含めたいですか?
アリB.フリードマン

2
@MatthewDowleできればまた+1したい。
アリB.フリードマン

3
@jabberwocky問題ありません。変数に含まれる列名を設定しながらset(DT, i, "V1", i)"V1"列をset(DT, i, colVar, i)設定しcolVarます(たとえば、colVar = "V1"以前に実行された場合)。引用符は、変数を検索するのではなく、文字通り列名を取得することを示しています。
Matt Dowle 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.