web-dev-qa-db-ja.com

data.tableを持つグループごとのサブセット

野球選手を含むデータテーブルがあるとします。

library(plyr)
library(data.table)

bdt <- as.data.table(baseball)

各プレイヤー(IDで指定)について、最も多くのゲームをプレイした年に対応する行を検索します。これはplyrで簡単です:

ddply(baseball, "id", subset, g == max(g))

Data.tableの同等のコードは何ですか?

私は試した:

setkey(bdt, "id") 
bdt[g == max(g)]  # only one row
bdt[g == max(g), by = id]  # Error: 'by' or 'keyby' is supplied but not j
bdt[, .SD[g == max(g)]] # only one row

これは動作します:

bdt[, .SD[g == max(g)], by = id] 

しかし、それはplyrよりも30%速いだけで、おそらく慣用的ではないことを示唆しています。

51
hadley

速いdata.table 仕方:

bdt[bdt[, .I[g == max(g)], by = id]$V1]

これにより、.SD、これは式のボトルネックです。

編集:実際、OPが遅い主な理由は、単に.SDが、特定の方法で使用しているという事実-[.data.tableは、現時点では大きなオーバーヘッドがあるため、ループで実行すると(byを実行すると)、非常に大きなペナルティが蓄積されます。

67
eddi