R:调用其他函数的函数速度

时间:2018-03-02 17:13:56

标签: r performance function

我在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

因此,将函数分成两部分并连续调用生成的两个函数会大大提高性能。我对此行为没有任何解释,并且想知道是否有人可以向我解释这一点,因为我经常使用调用其中两个或更多函数的函数。

提前致谢, 斯蒂芬

0 个答案:

没有答案