Data.tableを使用して、複数の小さなマージされたdata.frameで構成される大きなdata.frame(300k x 60)の処理を高速化しようとしています。 data.tableが初めてです。これまでのコードは次のとおりです
_library(data.table)
a = data.table(index=1:5,a=rnorm(5,10),b=rnorm(5,10),z=rnorm(5,10))
b = data.table(index=6:10,a=rnorm(5,10),b=rnorm(5,10),c=rnorm(5,10),d=rnorm(5,10))
dt = merge(a,b,by=intersect(names(a),names(b)),all=T)
dt$category = sample(letters[1:3],10,replace=T)
_
そして、データを要約するために以下よりも効率的な方法があるのではないかと思いました。
_summ = dt[i=T,j=list(a=sum(a,na.rm=T),b=sum(b,na.rm=T),c=sum(c,na.rm=T),
d=sum(d,na.rm=T),z=sum(z,na.rm=T)),by=category]
_
手動で50列すべての計算を入力したくはありませんが、eval(paste(...))
はどういうわけか不格好なようです。
以下の例を見てみましたが、私のニーズには少し複雑に思えます。ありがとう
.SD
で簡単なlapply
ステートメントを使用できます
dt[, lapply(.SD, sum, na.rm=TRUE), by=category ]
category index a b z c d
1: c 19 51.13289 48.49994 42.50884 9.535588 11.53253
2: b 9 17.34860 20.35022 10.32514 11.764105 10.53127
3: a 27 25.91616 31.12624 0.00000 29.197343 31.71285
特定の列のみを集計する場合は、.SDcols
引数を追加できます
# note that .SDcols also allows reordering of the columns
dt[, lapply(.SD, sum, na.rm=TRUE), by=category, .SDcols=c("a", "c", "z") ]
category a c z
1: c 51.13289 9.535588 42.50884
2: b 17.34860 11.764105 10.32514
3: a 25.91616 29.197343 0.00000
もちろん、これはsum
に限定されず、lapply
で匿名関数を含む任意の関数を使用できます。 (つまり、通常のlapply
ステートメントです)。
最後に、i=T
とj= <..>
を使用する必要はありません。個人的には、コードが読みにくくなると思いますが、それは単なるスタイル設定です。
.SD
および他のいくつかの特別な変数に関するドキュメントは、?"[.data.table"
のヘルプセクション([引数]セクションで、by
の情報を確認します)。
Data.tableもご覧くださいFAQ 2.1