【问题标题】:Shiny auto-update table or plot with invalidateLater()闪亮的自动更新表或带有 invalidateLater() 的绘图
【发布时间】:2017-08-29 19:53:14
【问题描述】:

我想了解为什么在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 秒后自动更新,因为每一秒都有新数据开始添加到绘制数据表。

感谢您分享任何建议或资源。

【问题讨论】:

  • 为什么不让RenderMyTable() 成为反应函数?

标签: r plot shiny auto-update


【解决方案1】:

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

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

这是一个工作版本的链接,我的想法来自: Shiny - 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 2018-04-30
    • 2022-10-04
    • 2015-01-27
    • 2020-12-23
    • 2014-10-11
    相关资源
    最近更新 更多