nI would like to use memoization to cache the results of some expensive operations so that they are not calculated over and over.
Both memoise and R.cache suit my needs. However, I find that caching is not reliable for calls.
Here is an example demonstrating the problem I am seeing:
library(memoise)
Updated based on answer
This question may have different answers based on whether persistent or non-persistent caching is used. Intermittent caching (e.g. memoise ) may require a separate assignment, and then the answer below is a great way. Persistent caching (e.g. R.cache ) works in all sessions and should be reliable across multiple destinations. The approach above works with R.cache . Despite multiple assignments, fn is only called once with R.cache . It will be called twice using memoise .
> 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
The reason I thought I was having a problem with R.cache because I was passing the proto method as a memoizedCall function. proto methods are tied to environments in such a way that R.cache has a hard time. In this case, you need to cancel the function (get from the created method to a simple function), and then pass the object manually as the first argument. The following example shows how this works (both Report and Report$loader are proto objects:
# This will not memoize the call memoizedCall(Report$loader$download_report)
I would really like to know why R.cache works with normal functions related to environments, but not using proto created methods.
source share