在闪亮的应用程序,它可以是很难使用迭代自参照。
这使我挠头的一个很大的,但是...
你提出的解决方案是不是在光泽做正确的事情,我强烈反对这样做。不要使用<<-
的分配,这是几乎从来没有光泽做正确的事情,它可能“似乎”的权利,但也意外情况,可导致莫名其妙的错误。通常,当你想使用<<-
,做正确的事情就是用reactiveVal()
。
考虑下面的应用程序使用<<-
节省运行数之和(我使用一个不同的样本应用程序比你要更简单,更容易理解):
ui <- fluidPage(
actionButton("add1", "Add 1"),
actionButton("add5", "Add 5")
)
server <- function(input, output) {
mysum <<- 0
observeEvent(input$add1, {
mysum <<- mysum + 1
print(mysum)
})
observeEvent(input$add5, {
mysum <<- mysum + 5
print(mysum)
})
}
shinyApp(ui, server)
上述应用会显得当你测试它的工作很好,但是当你把它在现实世界里,你会发现一个bug:如果你打开两个浏览器标签,该变量在两者之间共享。事实上,这个数字将在所有用户共享。因为你的初始分配使用<-
而第二个使用<<-
,但上面的图案是我看的很频繁,所以我想明确地表现出来,这将不会在您的应用程序发生。那是错的这里的另一件事是,现在,你离开的反应世界 - mysum
不是一个反应变量,所以我们不能有光泽使用它在任何情况下的反应(这就是为什么你的无解#2没”将不起作用)。下面是更好的方法:
ui <- fluidPage(
actionButton("add1", "Add 1"),
actionButton("add5", "Add 5")
)
server <- function(input, output) {
mysum <- reactiveVal(0)
observeEvent(input$add1, {
mysum(mysum() + 1)
})
observeEvent(input$add5, {
mysum(mysum() + 5)
})
observe({
print(mysum())
})
}
shinyApp(ui, server)
您可以阅读this answer了一下更深入的讨论
林张贴这帮助,如果任何人有试图从一个“迭代”到下一个闪亮的应用程序随身携带一个价值问题。
以我为例,我需要计算滑动平均。
library(shiny)
# UI
{
ui <- fluidPage(
textOutput('serial')
)
}
server <- function(input, output, session) {
serialStream <- reactive({
invalidateLater(10, session)
return(sample(1:100,1))
})
# Non-solution #1
# runningMean <- reactive({
# isolate(runningMean()*0.4) + serialStream()*0.1
# })
# output$serial <- renderText(runningMean())
# Non-solution #2
# runningMean <- 0 # initial value
# observe({
# runningMean <<- runningMean*0.4 + serialStream()*0.1
# })
# output$serial <- renderText(runningMean)
# Solution
rm <- 0 # initial value
runningMean <- reactive({
rm <<- rm * 0.4 + serialStream()*0.1
rm
})
output$serial <- renderText(runningMean())
}
# Run the application
shinyApp(ui = ui, server = server)
同样的事情也可以通过观察()来实现,但我遇到了内存泄漏问题。上面的代码不会把戏对我来说...注意使用<< - 而不是< - 无功函数内部。这确保RM的值是函数外部保存。