在Shiny应用程序中同时更新绘图和表格数据

时间:2018-07-19 13:15:29

标签: r shiny plotly dt

我有一些数据,我试图同时使用绘图(plotly)和表格(DT)逐行可视化每个观察线(每秒一行)。我没有问题让每个对象独立更新,但是我没有找到同时更新两个对象的正确方法。这是我一直在尝试的:

library(shiny)
library(DT)
library(plotly)

df <- matrix(rnorm(1000), nrow=1000, ncol=1)  # Data

ui <- fluidPage(
  sidebarLayout(

    sidebarPanel(align = "center",
      actionButton("button", "Start")
    ),

    mainPanel(
      column(width=6,
        plotlyOutput("plot")
      ),
      column(width=6,
        dataTableOutput("table")
      )
    )
  )
)

server <- function(input, output, session) {

  values <- reactiveValues (step = 1)           # Row index

  # Static Table
  output$table  <- renderDataTable({
    t(as.matrix(df[values$step, ]))  # First observation only
  })  

  # Static Plot
  p <- plot_ly(
    y = as.numeric(df[1, ]),  # First observation only
    type = "scatter",
    mode = 'lines'
  )
  output$plot <- renderPlotly(p)

  # Updating plot and table
  observeEvent(input$button, {
    time_0 <- Sys.time()  # Initial time

    while(TRUE){
      Sys.sleep(1)

      values$step <- difftime(Sys.time(), time_0, units="secs")  # Counting seconds since button hit

      dataTableProxy("table", session) %>%  # Table doesn't update
        replaceData(t(as.matrix(df[values$step, ])))

      plotlyProxy("plot", session) %>%  # Plot does update
        plotlyProxyInvoke("extendTraces", list(y=list(list(df[values$step, ]))), list(0))

    }
  })
}

shinyApp(ui = ui, server = server)

如果我将dataTableProxy调用放在observeEvent之外并且在其自己的observe中,它将按预期更新(每秒更新一次值),但是它将立即停止更新当我点击“开始”按钮时。然后,只有地块会更新,这就是为什么我认为如果将所有更新都放在同一个observeEvent中会更好,但是现在只有地块正在更新。为什么values$step每秒都在变化,表值却没有更新?

1 个答案:

答案 0 :(得分:1)

这似乎是一个范围界定问题(将t(as.matrix(df[1, ]))更改为t(as.matrix(df[values$step, ]))可以看到区别)。我找到了另一种解决方法,就是在自己的values$step中更新observe

library(shiny)
library(DT)
library(plotly)

df <- matrix(rnorm(1000), nrow=1000, ncol=1)  # Data

ui <- fluidPage(
  sidebarLayout(

    sidebarPanel("Empty panel"),

    mainPanel(
      column(width=6,
        plotlyOutput("plot")
      ),
      column(width=6,
        dataTableOutput("table")
      )
    )
  )
)

server <- function(input, output, session) {

  values <- reactiveValues (step = 1)  # Row index

  observe({
    invalidateLater(1000)

    isolate({
    values$step <- values$step + 1  # Updates after 1 second
    })
  })

  # Static Table
  output$table  <- renderDataTable({
    t(as.matrix(df[1, ]))  # First observation only
  })  

  # Static Plot
  p <- plot_ly(
    y = as.numeric(df[1, ]),  # First observation only
    type = "scatter",
    mode = 'lines'
  )
  output$plot <- renderPlotly(p)

  # Updating plot and table
  observe({

    dataTableProxy("table", session) %>%  # Table doesn't update
      replaceData(t(as.matrix(df[values$step, ])))

    plotlyProxy("plot", session) %>%  # Plot does update
      plotlyProxyInvoke("extendTraces", list(y=list(list(df[values$step, ]))), list(0))

  })
}

shinyApp(ui = ui, server = server)