Использование памятки в объектах R6
Все,
Я новичок в R6. Я пытаюсь создать частный объект, который кэшируется через memoise
функция. Фоновая идея состоит в том, что этот объект будет определяться вычислительно интенсивным вычислением, которое я хотел бы избежать повторного запуска после первого раза.
Я пытаюсь продублировать следующее поведение:
library(R6)
library(memoise)
library(digest)
Test <- memoise(function(x){
rnorm(1e8)
})
Test(1)
Test(1)
Вы должны заметить, что первым Test(1)
для запуска требуется секунда или две, тогда как вторая Test(1)
мгновенно
Мой MWE в мире R6:
factory <- R6Class("Test",
private = list(
..Z = memoise(
function(x){
rnorm(1e8)
}
)
),
active = list(
Z = function(value){
private$..Z(x=1)
}
)
)
object <- factory$new()
object$Z
Это должно показать мне rnorm(1e8)
, но вместо этого я получаю ошибку:
Error in private$..Z() : object 'cache' not found
Быстрое редактирование моего объекта позволяет мне узнать, что под капотом..Z выглядит так:
function (...)
{
hash <- digest(list(...))
if (cache$has_key(hash)) {
cache$get(hash)
}
else {
res <- f(...)
cache$set(hash, res)
res
}
}
Похоже, мне не удалось настроить мой memoise
, Глядя на вышесказанное, я не на 100% понимаю, как memoise
работает - как кеш существует если я его не вижу? Обычно not found
ошибки связаны с определением области видимости, что усложняется private
а также R6
,
1 ответ
Следующее работает хорошо для меня. Вам просто нужно реализовать кеширование самостоятельно
library(R6)
library(digest)
factory <- R6Class(
"Test",
private = list(
cache = list(),
..Z = function(x){
hash <- digest(x)
if (hash %in% names(private$cache)) {
private$cache[[hash]]
}
else {
res <- rnorm(1e7, x)
private$cache[[hash]] <- res
res
}
}
),
active = list(
Z = function(value){
private$..Z(x=1)
}
)
)
object <- factory$new()
## takes a while
object$Z
## returns "instantly"
object$Z