eventReactive 调用中 R Shiny 中的进度条
Progress Bar in R Shiny within an eventReactive call
我在我的 Shiny 应用程序中使用 eventReactive
调用来进行计算,从 10 秒到 10000 秒不等。我想向我的用户展示我们在循环中有多远。我无法使用 shiny 提供的 example,因为我需要存储来自 eventReactive
调用的几个对象。我提供了一个简化的示例,其中在 R 控制台上生成了一种 'progress bar',但我不知道如何在 Shiny 中获得类似的东西。请注意,稍后我需要在绘图中使用 dat1、dat2 和 dat3。代码:
# This function computes a new data set. It can optionally take a function,
# updateProgress, which will be called as each row of data is added.
compute_data <- function(updateProgress = NULL) {
# Create 0-row data frame which will be used to store data
dat <- data.frame(x = numeric(0), y = numeric(0))
for (i in 1:10) {
Sys.sleep(0.25)
# Compute new row of data
new_row <- data.frame(x = rnorm(1), y = rnorm(1))
# If we were passed a progress update function, call it
if (is.function(updateProgress)) {
text <- paste0("x:", round(new_row$x, 2), " y:", round(new_row$y, 2))
updateProgress(detail = text)
}
# Add the new row of data
dat <- rbind(dat, new_row)
}
dat
}
server <- function(input, output) {
output$table <- renderTable({
input$goTable
# Create a Progress object
progress <- shiny::Progress$new()
progress$set(message = "Computing data", value = 0)
# Close the progress when this reactive exits (even if there's an error)
on.exit(progress$close())
# Create a callback function to update progress.
# Each time this is called:
# - If `value` is NULL, it will move the progress bar 1/5 of the remaining
# distance. If non-NULL, it will set the progress to that value.
# - It also accepts optional detail text.
updateProgress <- function(value = NULL, detail = NULL) {
if (is.null(value)) {
value <- progress$getValue()
value <- value + (progress$getMax() - value) / 5
}
progress$set(value = value, detail = detail)
}
# Compute the new data, and pass in the updateProgress function so
# that it can update the progress indicator.
compute_data(updateProgress)
})
Test <- eventReactive(input$goTable,{
n <- 10
dat1 <- data.frame(x = numeric(0), y = numeric(0))
dat2 <- data.frame(x = numeric(0), y = numeric(0))
dat3 <- data.frame(x = numeric(0), y = numeric(0))
for (i in 1:n) {
print(paste0(i*10,"%"))
# Each time through the loop, add another row of data. This is
# a stand-in for a long-running computation.
dat1 <- rbind(dat1, data.frame(x = rnorm(1), y = rnorm(1)))
dat2 <- rbind(dat2, data.frame(x = rnorm(1), y = rnorm(1)))
dat3 <- rbind(dat3, data.frame(x = rnorm(1), y = rnorm(1)))
# Increment the progress bar, and update the detail text.
#incProgress(1/n, detail = paste("Doing part", i))
# Pause for 0.1 seconds to simulate a long computation.
Sys.sleep(0.5)
}
list(dat1,dat2,dat3)
})
output$table1 <- renderTable({Test()[[1]]})
output$table2 <- renderTable({Test()[[2]]})
output$table3 <- renderTable({Test()[[3]]})
}
ui <- shinyUI(basicPage(
#tableOutput('table1'),
actionButton('goTable', 'Start Computing..'),
tableOutput('table1'),
tableOutput('table2'),
tableOutput('table3')
))
shinyApp(ui = ui, server = server)
非常感谢任何帮助。
似乎可以在您的 eventReactive 调用中使用弹出进度条功能:
for (i in 1:100) {
Sys.sleep(.05)
info <- sprintf("%d%% done", round((i/100)*100))
setWinProgressBar(pb, i/(100)*100, label=info)
}; close(pb)
我在我的 Shiny 应用程序中使用 eventReactive
调用来进行计算,从 10 秒到 10000 秒不等。我想向我的用户展示我们在循环中有多远。我无法使用 shiny 提供的 example,因为我需要存储来自 eventReactive
调用的几个对象。我提供了一个简化的示例,其中在 R 控制台上生成了一种 'progress bar',但我不知道如何在 Shiny 中获得类似的东西。请注意,稍后我需要在绘图中使用 dat1、dat2 和 dat3。代码:
# This function computes a new data set. It can optionally take a function,
# updateProgress, which will be called as each row of data is added.
compute_data <- function(updateProgress = NULL) {
# Create 0-row data frame which will be used to store data
dat <- data.frame(x = numeric(0), y = numeric(0))
for (i in 1:10) {
Sys.sleep(0.25)
# Compute new row of data
new_row <- data.frame(x = rnorm(1), y = rnorm(1))
# If we were passed a progress update function, call it
if (is.function(updateProgress)) {
text <- paste0("x:", round(new_row$x, 2), " y:", round(new_row$y, 2))
updateProgress(detail = text)
}
# Add the new row of data
dat <- rbind(dat, new_row)
}
dat
}
server <- function(input, output) {
output$table <- renderTable({
input$goTable
# Create a Progress object
progress <- shiny::Progress$new()
progress$set(message = "Computing data", value = 0)
# Close the progress when this reactive exits (even if there's an error)
on.exit(progress$close())
# Create a callback function to update progress.
# Each time this is called:
# - If `value` is NULL, it will move the progress bar 1/5 of the remaining
# distance. If non-NULL, it will set the progress to that value.
# - It also accepts optional detail text.
updateProgress <- function(value = NULL, detail = NULL) {
if (is.null(value)) {
value <- progress$getValue()
value <- value + (progress$getMax() - value) / 5
}
progress$set(value = value, detail = detail)
}
# Compute the new data, and pass in the updateProgress function so
# that it can update the progress indicator.
compute_data(updateProgress)
})
Test <- eventReactive(input$goTable,{
n <- 10
dat1 <- data.frame(x = numeric(0), y = numeric(0))
dat2 <- data.frame(x = numeric(0), y = numeric(0))
dat3 <- data.frame(x = numeric(0), y = numeric(0))
for (i in 1:n) {
print(paste0(i*10,"%"))
# Each time through the loop, add another row of data. This is
# a stand-in for a long-running computation.
dat1 <- rbind(dat1, data.frame(x = rnorm(1), y = rnorm(1)))
dat2 <- rbind(dat2, data.frame(x = rnorm(1), y = rnorm(1)))
dat3 <- rbind(dat3, data.frame(x = rnorm(1), y = rnorm(1)))
# Increment the progress bar, and update the detail text.
#incProgress(1/n, detail = paste("Doing part", i))
# Pause for 0.1 seconds to simulate a long computation.
Sys.sleep(0.5)
}
list(dat1,dat2,dat3)
})
output$table1 <- renderTable({Test()[[1]]})
output$table2 <- renderTable({Test()[[2]]})
output$table3 <- renderTable({Test()[[3]]})
}
ui <- shinyUI(basicPage(
#tableOutput('table1'),
actionButton('goTable', 'Start Computing..'),
tableOutput('table1'),
tableOutput('table2'),
tableOutput('table3')
))
shinyApp(ui = ui, server = server)
非常感谢任何帮助。
似乎可以在您的 eventReactive 调用中使用弹出进度条功能:
for (i in 1:100) {
Sys.sleep(.05)
info <- sprintf("%d%% done", round((i/100)*100))
setWinProgressBar(pb, i/(100)*100, label=info)
}; close(pb)