Использование памятки в объектах 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
Другие вопросы по тегам