r-缓存函数内生成的计算开销较大的对象的正确方法



背景

在下面的场景中,我看到以下工作流程:

  1. 顶级runner函数,在下面的running_function示例中,调用许多较小的函数
  2. 其中一些函数在计算上是可扩展的,并且将在同一组参数上重复调用,因为据说顶级脚本会调用runner函数

示例

如果不尝试缓存对象,情况可以总结如下:

工作职能

painful_function <- function(n = 100) {
matrix(1:n * n, nrow = n)
}
running_function <-
function(stat_to_do = c("min", "max", "mean", "sum"),
painful_size = 1e4) {
stat_to_do <- match.arg(stat_to_do)
M_pain <- painful_function(n = painful_size)
do.call(stat_to_do, list(M_pain))
}

实际作业

# Object M_pain is created inside running_function
running_function(stat_to_do = "min", painful_size = 100)
# I would like to re-use the M_pain object from the previous function
running_function(stat_to_do = "max", painful_size = 100)
# Re-using M_pain again...
running_function(stat_to_do = "mean", painful_size = 100)
# And again ...
running_function(stat_to_do = "sum", painful_size = 100)

期望的结果

其思想是不要多次调用painful_function,因为它生成的对象在每个场景中都是相同的。running_function应使用提供的参数进行评估。

方法

我正在考虑使用mustashe包:

library("mustashe")
running_function_mstash <-
function(stat_to_do = c("min", "max", "mean", "sum"),
painful_size = 1e4) {
stat_to_do <- match.arg(stat_to_do)
stash(var = "M_pain",
code = {
painful_function(n = painful_size)
},
depends_on = "painful_size")
do.call(stat_to_do, list(M_pain))
}

这将返回以下错误:

running_function_mstash(stat_to_do = "min", painful_size = 1e6)

make_hash(dependents_on,.TargetEnv(中出错:环境中缺少一些依赖项。

问题

我有兴趣学习以下内容:

  1. 如何实现这一点,即如果传递的参数之一发生更改,running_function将仅执行painful_function,如果不是,则结果对象存储在文件中
  2. 有什么更好的方法可以使用它。一个琐碎的";暴力";一种方法是创建一个具有时髦名称的临时RDS,并且只有在文件不存在的情况下才执行painful_function。这种蹩脚的方法有明显的缺点。我想找到一个强大的解决方案,涵盖类似的,可行的场景

可能是没有检测到对象。根据?stash中的示例,我们需要使用<<-

running_function_mstash <-
function(stat_to_do = c("min", "max", "mean", "sum"),
painful_size = 1e4) {
stat_to_do <- match.arg(stat_to_do)
painful_size <<- painful_size
stash(var = "M_pain",
code = {
painful_function(n = painful_size)
},
depends_on = "painful_size")
do.call(stat_to_do, list(M_pain))
}
running_function_mstash(stat_to_do = "min", painful_size = 1e6)
#Stashing object.
#[1] 1e+06

最新更新