【发布时间】:2021-03-22 15:51:08
【问题描述】:
我在 R 中运行了大量繁重的计算,我正在尝试编写一个函数来帮助我缓存我的结果,并且只在必要时计算它们。我想出了这个:
memoize <- function(filename, fun, ...){
if(file.exists(filename)){
message(paste("Reading", filename))
return(readRDS(filename))
} else {
message(paste(filename, "not found, running computations"))
result <- do.call(fun, list(...))
message(paste("Writing", filename))
saveRDS(result, filename)
return(result)
}
}
这让我可以这样做:
result <- memoize("test.rds", function(){ return(runif(100))} )
这很好用,但是,我希望能够不使用“function()”部分,即传递表达式而不是函数。这可以按如下方式完成:
memoize <- function(filename, expr){
if(file.exists(filename)){
message(paste("Reading", filename))
return(readRDS(filename))
} else {
message(paste(filename, "not found, running computations"))
f <- function(){}
body(f) <- expr
environment(f) <- parent.frame()
result <- do.call(f, list())
message(paste("Writing", filename))
saveRDS(result, filename)
return(result)
}
}
根据capturing an expression as a function body in R
使用时效果很好
result <- memoize("test.rds", { runif(100)} )
但是,我想在该表达式中保留显式的 return() 语句。当我尝试时
result <- memoize("test.rds", { return(runif(100))} )
我明白了
没有函数返回,跳转到顶层
我显然误解了它的工作原理:为什么 expr 似乎在绑定到 f 之前被评估?我怎样才能做到这一点?
【问题讨论】:
-
我很清楚这一点,但这是个人喜好问题,显然是问题的关键部分。
-
我认为
memoise包可能是它的就地替代品,而且效果很好。
标签: r