[英]match.fun slower than actual function in 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對象。
原因是gforce優化data.table用於median
。 您可以看到是否設置了options(datatable.verbose=TRUE)
。 有關詳細信息,請參見help("GForce")
。
如果將其他功能進行比較,則會得到更多類似的計時:
fun <- median
aggFn <- "fun"
system.time(dat[, lapply(.SD, fun), by=id])
system.time(dat[, lapply(.SD, match.fun(aggFn)), by=id])
如果碰巧支持該函數,則可能要利用優化來解決該問題,例如,使用可怕的eval(parse())
來評估表達式構建:
dat[, eval(parse(text = sprintf("lapply(.SD, %s)", aggFn))), by=id]
但是,使用match.fun
會增加安全性。
如果您有用戶可以選擇的功能列表,則可以執行以下操作:
funs <- list(quote(mean), quote(median))
fun <- funs[[1]] #select
expr <- bquote(lapply(.SD, .(fun)))
a <- dat[, eval(expr), by=id]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.