私は、同じものを測定する行を持つ大きなデータセットを持っています(本質的にノイズで重複します)。私が書いているより大きな関数の一環として、ユーザーは選択した関数(例えば、平均、中央値)でこれらの行を折りたたむことができます。match.funは実際の関数よりも遅いR
私の問題は、関数を直接呼び出すと、match.fun(私が必要とするもの)を使うよりもスピードがはるかに速いことです。 MWE:私のシステムで
require(data.table)
rows <- 100000
cols <- 1000
dat <- data.table(id=sample(LETTERS, rows, replace=TRUE),
matrix(rnorm(rows*cols), nrow=rows))
aggFn <- "median"
system.time(dat[, lapply(.SD, median), by=id])
system.time(dat[, lapply(.SD, match.fun(aggFn)), by=id])
、最後の2行の結果タイミング:これは、大規模なデータセットで劇的になり
user system elapsed
1.112 0.027 1.141
user system elapsed
2.854 0.265 3.121
を。
最終的には、aggregate()がこれを行うことができます(この動作には苦しんでいないようです)が、データサイズのためdata.tableオブジェクトで作業する必要があります。
理由だけで、その後 'lapply('あなたのループの外 'F = match.fun(aggFn)を行いません。 SD、f) '。 'match.fun'は関数そのものよりも遅いことは明らかです。 'match.fun'のコードを見ると、基本的に' get'が実行され、 'aggFn'が本当に関数であることが保証されています。 'aggFn'が既に関数であることを知っていれば、' match.fun'を使う必要はありません。 – MichaelChirico
これは大規模なデータに対しては非常に劇的になると言いますが、 'rows = 1e3; cols = 1e4'となり、時間の増加率は実際にあなたの例に比べて下がりました...マイケルの提案に加えて、 'e = substitute(lapply(.SD、aggFn)、list(aggFn =" median ")); system.time(dat [、eval(e)、by = id]) '、data.table FAQに記載されています。 – Frank
実際には、match.funを使用しているときにGForceがトリガされないため、実際には速度の差があります。 '?GForce'を参照して、' dat [、lapply(.SD、median)、by = id、verbose = TRUE] 'のような' verbose = TRUE'を使ってクエリを実行してみてください。 ' – Frank