22

Shiny tutorial,有一个例子:

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 })
})
4

1 回答 1

26

在这种情况下使用 currentFib <- reactiveValues({ fib(as.numeric(input$n)) })将不起作用。您将收到一条错误消息,指出您正在访问“反应式上下文”之外的反应式值。

但是,如果您将其包装在函数调用中,它将起作用:

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

这是有效的,因为现在函数调用位于反应式上下文中。

关键区别在于它们在Shiny 文档中对反应性“源”和“导体”的区别。在那个术语中,reactive({...})导体,但reactiveValues只能是

  • 这就是我的想法reactiveValues- 作为一种扩展UI.Rinput中指定的方式。有时,其中的插槽是不够的,我们想要基于这些输入插槽的派生值。换句话说,它是一种扩展槽列表以供未来反应式计算的方法。inputinput

  • Reactive()照你说的做——它在每次任何反应性值发生变化时重新运行表达式后返回值。如果您查看源代码,reactive您可以看到:最后一行是返回的缓存值:Observable$new(fun, label)$getValue其中 'fun' 是在调用中发送的表达式reactive.

于 2013-08-20T07:22:35.150 回答