Подтвердить что ты не робот

Какая разница между реактивной стоимостью и реактивным выражением?

В Блестящий учебник, есть пример:

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))

shinyServer(function(input, output) {
  currentFib         <- reactive({ fib(as.numeric(input$n)) })

  output$nthValue    <- renderText({ currentFib() })
  output$nthValueInv <- renderText({ 1 / currentFib() })
})

Я не понимаю, как reactive кэширует значения. Внутренне ли что-то вроде return(function() cachedValue)? Теперь мне интересно, могу ли я это сделать?

fib <- function(n) ifelse(n<3, 1, fib(n-1)+fib(n-2))

shinyServer(function(input, output) {
  currentFib         <- reactiveValues({ fib(as.numeric(input$n)) })

  output$nthValue    <- renderText({ currentFib })
  output$nthValueInv <- renderText({ 1 / currentFib })
})
4b9b3361

Ответ 1

Использование currentFib <- reactiveValues({ fib(as.numeric(input$n)) }) не будет работать в этом контексте. Вы получите сообщение о том, что вы получаете доступ к реактивным значениям вне "реактивного контекста".

Однако, если вы вместо этого перевернете его внутри вызова функции, он будет работать:

currentFib <- function(){ fib(as.numeric(input$n)) }

Это работает, потому что теперь вызов функции находится внутри реактивного контекста.

Различие клавиш - это различие, которое они делают в блестящей документации, между реактивными "источниками" и "проводниками". В этой терминологии reactive({...}) является проводником, но reactiveValues может быть только источником.

  • Вот как я думаю о reactiveValues - как способ расширения input, который указан в UI.R. Иногда слотов в input недостаточно, и нам нужны производные значения на основе этих входных слотов. Другими словами, это способ расширить список слотов input для будущих реактивных вычислений.

  • Reactive() делает то, что вы говорите, - оно возвращает значение после повторного запуска выражения каждый раз при изменении любого реактивного значения. Если вы посмотрите на исходный код для reactive, вы можете увидеть его: Последняя строка - это кэшированное значение, которое возвращается: Observable$new(fun, label)$getValue где "fun" - это выражение, которое было отправлено при вызове reactive.