web-dev-qa-db-ja.com

data.tableを使用して複数の列を要約する

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(...))はどういうわけか不格好なようです。

以下の例を見てみましたが、私のニーズには少し複雑に思えます。ありがとう

複数の列にわたってdata.tableを要約する方法

51
Tahnoon Pasha

.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=Tj= <..>を使用する必要はありません。個人的には、コードが読みにくくなると思いますが、それは単なるスタイル設定です。


編集:ドキュメント

.SDおよび他のいくつかの特別な変数に関するドキュメントは、
?"[.data.table"のヘルプセクション([引数]セクションで、byの情報を確認します)。

Data.tableもご覧くださいFAQ 2.1

http://datatable.r-forge.r-project.org/datatable-faq.pdf

86
Ricardo Saporta