我在R中使用一个函数,其中生成了许多数据集并将其保存在列表中(使用lapply)。然后使用lme4包的lmer函数(再次使用lapply)评估这些数据集。
这是主函数以及用于估计模型的辅助函数(= estimate_model)和生成数据集的函数(= generate_data):
estimate_model <- function(est.model,data) {
tmp <- lme4::lmer(formula(est.model),data=data)
fixeff <- getME(tmp,"fixef")
resvar <- getME(tmp,"sigma")^2
raneff <- as.data.frame(VarCorr(tmp))$vcov[1:3]
res <- c(fixeff,raneff,resvar)
res
}
generate_data <- function(est.model, no.samples) {
# get some things
data <- est.model@frame
data.star <- lapply(1:no.samples,function(x) { res = data; res; })
return(data.star)
}
main_function <- function(est.model, no.samples) {
# generate data
data.star = generate_data(est.model,no.samples)
# evaluate the datasets
b.fit = lapply(data.star,function(x) { estimate_model(est.model,x) })
b.fit = t(do.call("rbind",b.fit))
# output
return(b.fit)
}
该函数调用generate_data函数,其中使用估计的lme4对象生成许多新数据集(由no.samples定义),这些数据集保存在列表中,然后使用lmer评估列表的每个元素在estimate_model函数中调用的函数。
现在,我的问题或疑问。当我运行我的代码并使用system.time来检查函数的速度时,我发现我的计算机需要大约24秒才能获得no.samples = 100.代码会喜欢这个
library(nlme)
library(lme4)
# some example data
dfs <- Orthodont
fit <- lmer(distance ~ 1 + age + (1 + age|Subject), data = dfs)
# speed of the function
system.time(main_function(fit, no.samples = 100))
... 23.24 seconds
这很慢并且由于意外事故我观察到当我将main函数拆分为generate_data函数和另一个基本包含b.fit-lines的函数时,例如
call_to_estimate <- function(data.star,est.model) {
# fit the model to all B-samples
b.fit = lapply(data.star,function(x) { estimate_model(est.model,x) })
b.fit = t(do.call("rbind",b.fit))
return(b.fit)
}
然后独立调用这两个函数,然后这要快得多。例如,对于100个样本,代码和时间是
system.time(XX <- generate_data(fit, no.samples = 100))
...0 seconds
system.time(call_to_estimate(XX,fit))
.. 4.55 seconds
因此,将函数分成两部分并连续调用生成的两个函数会大大提高性能。我对此行为没有任何解释,并且想知道是否有人可以向我解释这一点,因为我经常使用调用其中两个或更多函数的函数。
提前致谢, 斯蒂芬