在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 })
})
答案 0 :(得分:22)
使用
currentFib <- reactiveValues({ fib(as.numeric(input$n)) })
在这种情况下不起作用。
您将收到一条错误消息,指出您正在访问“反应性上下文”之外的被动值。
但是,如果将它包装在函数调用中,它将起作用:
currentFib <- function(){ fib(as.numeric(input$n)) }
这是有效的,因为现在函数调用在一个被动上下文中。
关键差异是他们在Shiny documentation中,在被动“源”和“指挥”之间的区别。在该术语中,reactive({...})
是指挥,但reactiveValues
只能是来源。
以下是我对reactiveValues
的看法 - 作为扩展{em> UI.R中指定的input
的方法。有时,{{1}中的广告位还不够,我们希望基于这些输入槽的派生值。换句话说,它是一种扩展input
时隙列表以便将来进行反应计算的方法。
input
按照你说的做法 - 每当任何无效值发生变化时,它会在重新运行表达式后返回值。如果查看源代码Reactive()
你可以看到它:
最后一行是返回的缓存值:reactive
其中“fun”是调用Observable$new(fun, label)$getValue