问题
I have a library with custom functions and I need to use one in a shiny app. This function has a for loop inside it and I want to use the variable in that loop to update a progress bar (instead of copying the function to the server file, because I want to keep everything separate and clean). So far, I've managed to get a message to pop up when the function is running with "withProgress()", but I would like to make it even nicer showing the % of the job that is done, so the end users don't spam the run button. This is a reproducible example of the problem:
library(shiny)
# Library in separate file
snail_function <- function(){
for (i in 1:100){
Sys.sleep(1)
}
}
# ui.R
ui <- shinyUI(fluidPage(
tabsetPanel(
tabPanel("1. Load Files"
, fluidRow(actionButton("analysis", "Run analysis"))
, fluidRow(
plotOutput("bar")
)
)
)
))
# server.R
server <- shinyServer(function(input, output, session) {
observeEvent(input$analysis, {
output$bar <- renderPlot({
withProgress(message = 'Running... (this may take a while)',
detail = 'Go get some coffee...', value = 0, {
snail_function()
})
# do stuff
})
})
})
shinyApp(ui = ui, server = server)
So, I guess the question is: is there any way I could use i from the snail_function loop to set the progress in the bar? (with a global variable or something of the sort)
Thanks!
回答1:
One possibility to keep it a clean solution would be to add a parameter progress to the function, that indicates if we want to increase progress, and call incProgress only when this is set to TRUE. So when we want to run this function standalone, we can call it as snail_function(FALSE). A working example is shown below, hope this helps.
library(shiny)
# Library in separate file
snail_function <- function(progress=FALSE){
for (i in 1:100){
Sys.sleep(1)
if(progress)
incProgress(1/100)
}
}
# ui.R
ui <- shinyUI(fluidPage(
tabsetPanel(
tabPanel("1. Load Files"
, fluidRow(actionButton("analysis", "Run analysis"))
, fluidRow(
plotOutput("bar")
)
)
)
))
# server.R
server <- shinyServer(function(input, output, session) {
observeEvent(input$analysis, {
output$bar <- renderPlot({
withProgress(message = 'Running... (this may take a while)',
detail = 'Go get some coffee...', value = 0, {
snail_function(progress=TRUE)
})
# do stuff
})
})
})
shinyApp(ui,server)
来源:https://stackoverflow.com/questions/49727660/shiny-progress-bar-from-a-global-variable