r-使用invalidateLater()自动更新表或绘图



我想了解为什么在observeEvent()内部使用invalidateLater()时不会自动更新下表。我已经准备了以下程序来说明我的问题,"mytable2"使用reactiveTimer(),并且确实产生了所需的输出,但是"mytable"使用invalidateLater(),并且除非我单击"更新"按钮,否则不会自动更新。为什么?

library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("update", "Update")
),
mainPanel(
column(6, tableOutput('mytable')),
column(6, tableOutput('mytable2'))
)
)
)
server <- function(input, output) {
values <- reactiveValues(df   = RenderMyTable())
observeEvent(invalidateLater(1000), {
values$df <- RenderMyTable()  # This does not update after 1 sec
})
observeEvent(input$update, {
values$df <- RenderMyTable()  # This does update upon clicking
})
output$mytable  <- renderTable(values$df)  # Depends on reactiveValues
autoInvalidate <- reactiveTimer(1000)
output$mytable2 <- renderTable({
autoInvalidate()
RenderMyTable()  # >This does update after 1 sec
})
}
time1 <- Sys.time()  # Start time
df <- data.frame(a = 1:1000)  # Some data
RenderMyTable <- function(){
# Seconds since start time
time2 <- as.integer(difftime(Sys.time(), time1, units="secs"))
df.now <- df[1:time2,]  # Updates each second
df.now
}
shinyApp(ui = ui, server = server)

后续问题

此外,让情节自动更新的合适方法是什么(就像"mytable2"一样(?到目前为止,我更新绘图的唯一方法是使用上面"mytable"中的"更新"按钮,但我希望它在1秒后自动更新,因为每秒钟都有新数据开始添加到绘图数据表中。

如能提供任何建议或资源,我们将不胜感激。

首先,我想说,我从这段代码中学到了一些东西,这是一种非常巧妙的自动化绘图更改的方法,所以谢谢你,我将来也会使用它。

对于您的问题,我已经研究了invalidateLater,它是由反应和观察函数组成的,正如您所研究的那样。只需将observeEvent更改为observe,并将invalidateLater函数移动到代码的主块中,而不是将其作为参数传递,就可以在第一个表输出中解决此问题。

以下是我从中获得想法的工作版本的链接:闪亮-无效后期

对于您的后续问题,我们可以通过与以前完全相同的过程来完成:

output$autoupdate_plot <- renderPlot({
invalidateLater(2000)
hist(rnorm(isolate(RenderMyTable())))
})

现在将等待2秒钟,然后再运行该功能。当值发生变化时,我们使用isolate来避免更新,但只有当我们决定时才更新,在这种情况下是在2秒的间隔上。

下面的完整代码是您非常创新的工作的扩展:

app.R

library(shiny)
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
actionButton("update", "Update")
),
mainPanel(
column(4, tableOutput('mytable')),
column(4, tableOutput('mytable2')),
column(4, plotOutput("autoupdate_plot"))
)

)
)
server <- function(input, output) {
values <- reactiveValues(df = RenderMyTable())
observe({
invalidateLater(1000)
values$df <- RenderMyTable()  # This does not update after 1 sec
})
observeEvent(input$update, {
values$df <- RenderMyTable()  # This does update upon clicking
})
output$mytable  <- renderTable(values$df)  # Depends on reactiveValues
autoInvalidate <- reactiveTimer(1000)
output$mytable2 <- renderTable({
autoInvalidate()
RenderMyTable()  # >This does update after 1 sec
})
output$autoupdate_plot <- renderPlot({
invalidateLater(2000)
hist(rnorm(isolate(RenderMyTable())), main = "Auto Hist")
})
}
time1 <- Sys.time()  # Start time
df <- data.frame(a = 1:1000)  # Some data
RenderMyTable <- function(){
# Seconds since start time
time2 <- as.integer(difftime(Sys.time(), time1, units="secs"))
df.now <- df[1:time2,]  # Updates each second
df.now
}
shinyApp(ui = ui, server = server)

最新更新