闪亮的自动更新 table 或使用 invalidateLater() 绘图
Shiny auto-update table or plot with invalidateLater()
我想了解为什么在 observeEvent()
中使用 invalidateLater()
时以下 table 不会自动更新。我准备了以下程序来说明我的问题,"mytable2" 使用 reactiveTimer()
并确实产生了所需的输出,但是 "mytable" 使用 invalidateLater()
并且不会自动更新,除非我单击 "update" 按钮。为什么?
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" 中的 "update" 按钮,但我希望它在 1 秒后自动更新,因为每秒都有新数据开始添加到绘图数据 table.
感谢您分享任何建议或资源。
首先,我想说我从这段代码中学到了一些东西,这是一种非常巧妙的自动更改情节的方法,所以谢谢你,我将来会使用它。
对于你的问题,我已经研究了 invalidateLater
,正如你所努力的那样,它可以通过反应和观察功能发挥作用。只需从 observeEvent
更改为 observe
并将 invalidateLater
函数移动到代码的主块中,而不是将其作为参数传递,即可在第一个 table 上解决此问题输出。
这是一个 link 的工作版本,我的想法来自于:
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)
我想了解为什么在 observeEvent()
中使用 invalidateLater()
时以下 table 不会自动更新。我准备了以下程序来说明我的问题,"mytable2" 使用 reactiveTimer()
并确实产生了所需的输出,但是 "mytable" 使用 invalidateLater()
并且不会自动更新,除非我单击 "update" 按钮。为什么?
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" 中的 "update" 按钮,但我希望它在 1 秒后自动更新,因为每秒都有新数据开始添加到绘图数据 table.
感谢您分享任何建议或资源。
首先,我想说我从这段代码中学到了一些东西,这是一种非常巧妙的自动更改情节的方法,所以谢谢你,我将来会使用它。
对于你的问题,我已经研究了 invalidateLater
,正如你所努力的那样,它可以通过反应和观察功能发挥作用。只需从 observeEvent
更改为 observe
并将 invalidateLater
函数移动到代码的主块中,而不是将其作为参数传递,即可在第一个 table 上解决此问题输出。
这是一个 link 的工作版本,我的想法来自于: 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)