首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >R:环境缓存/回忆录

R:环境缓存/回忆录
EN

Stack Overflow用户
提问于 2012-07-06 07:21:32
回答 2查看 963关注 0票数 6

nI希望使用回忆录缓存某些昂贵操作的结果,这样就不会一次又一次地计算结果。

回忆录R.cache都符合我的需要。但是,我发现缓存在调用中并不健壮。

下面是一个演示我所看到的问题的例子:

代码语言:javascript
复制
library(memoise)

# Memoisation works: b() is called only once
a <- function(x) runif(1)
replicate(5, a())
b <- memoise(a)
replicate(5, b())

# Memoisation fails: mfn() is called every single time
ProtoTester <- proto(
  calc = function(.) {
    fn <- function() print(runif(1))
    mfn <- memoise(fn)
    invisible(mfn())
  }      
)
replicate(5, ProtoTester$calc())

基于答案的更新

根据是否使用持久缓存或非持久缓存,此问题可能有不同的答案。非持久缓存(如memoise)可能需要单次赋值,然后下面的答案是一个很好的方法。持久缓存(如R.cache)跨会话工作,对于多个赋值应该是健壮的。上述方法适用于R.cache。尽管有多个任务分配,fnR.cache中只被调用一次。它将在memoise中调用两次。

代码语言:javascript
复制
> ProtoTester <- proto(
+     calc = function(.) {
+         fn <- function() print(runif(1))
+         invisible(memoizedCall(fn))
+     }      
+ )
> replicate(5, ProtoTester$calc())
[1] 0.977563
[1] 0.1279641
[1] 0.01358866
[1] 0.9993092
[1] 0.3114813
[1] 0.97756303 0.12796408 0.01358866 0.99930922 0.31148128
> ProtoTester <- proto(
+     calc = function(.) {
+         fn <- function() print(runif(1))
+         invisible(memoizedCall(fn))
+     }      
+ )
> replicate(5, ProtoTester$calc())
[1] 0.97756303 0.12796408 0.01358866 0.99930922 0.31148128

我认为我对R.cache有问题的原因是我将一个proto方法作为函数传递给memoizedCallproto方法以R.cache难以使用的方式绑定到环境。在这种情况下,您必须做的是解除函数的绑定(从实例化的方法获取到一个简单的函数),然后手动传递对象作为第一个参数。下面的示例说明了这是如何工作的( ReportReport$loader都是proto对象:

代码语言:javascript
复制
# This will not memoize the call
memoizedCall(Report$loader$download_report)

# This works as intended
memoizedCall(with(Report$loader, download_report), Report$loader)

我很想知道为什么R.cache与绑定到环境的正常函数一起工作,但是proto实例化方法却失败了。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-06 07:45:02

在您的代码中,每次调用该函数时都会重新对其进行回溯。以下几点应该奏效:它只有一次回忆录,当它被定义时。

代码语言:javascript
复制
ProtoTester <- proto(
  calc = {
    fn <- function() print(runif(1))
    mfn <- memoise(fn)
    function(.) mfn()
  }
)
replicate(5, ProtoTester$calc())
票数 5
EN

Stack Overflow用户

发布于 2012-07-06 08:01:44

另一种解决方案是使用evals从(my) 压盘包装进行评估,后者具有内部(当前R会话环境中的临时或磁盘存储持久的)缓存引擎。基于代码的简短示例:

代码语言:javascript
复制
library(pander)
ProtoTester <- proto(
  calc = function(.) {
    fn <- function() runif(1)
    mfn <- evals('fn()')[[1]]$result
    invisible(mfn)
  }      
)

并且在缓存中断断续续地运行evals将导致:

代码语言:javascript
复制
> evals.option('cache', FALSE)
> replicate(5, ProtoTester$calc())
[1] 0.7152186 0.4529955 0.4160411 0.1166872 0.8776698

> evals.option('cache', TRUE)
> evals.option('cache.time', 0)
> replicate(5, ProtoTester$calc())
[1] 0.7716874 0.7716874 0.7716874 0.7716874 0.7716874

请注意,evals.option函数si将很快重命名为evalsOption,以减轻对S3方法的R CMD check警告。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11357602

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档