在闪亮的应用程序中,使用迭代自引用可能很困难。
这使我挠头,但是...
答案 0 :(得分:0)
如果有其他人尝试在闪亮的应用程序中将值从一个“迭代”传递到下一个“迭代”时遇到问题,我会发布此信息以提供帮助。
就我而言,我需要计算一个移动平均值。
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)
使用observe()可以完成类似的事情,但是我遇到了内存泄漏问题。上面的代码对我有用。...请注意在反应函数内部使用<<-代替<-。这样可以确保rm的值保留在该函数之外。
答案 1 :(得分:0)
您提出的解决方案不是正确的方法,我强烈建议您不要这样做。不要使用<<-
进行赋值,这几乎从来都不是正确的选择,它可能看起来“正确”,但是具有意想不到的行为,可能导致奇怪的错误。通常,当您要使用<<-
时,正确的做法是使用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)
上面的应用程序在测试时似乎可以正常运行,但是当您将其发布到现实世界中时,您会注意到一个错误:如果打开两个浏览器选项卡,则变量将在两者之间共享。实际上,该号码将在所有用户之间共享。在您的应用中不会发生这种情况,因为您的初始分配使用了<-
,而第二次分配使用了<<-
,但是上面的模式是我经常看到的,所以我想明确地显示它。另一个错误是,您现在已经离开了反应性世界-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进行更深入的讨论