问题
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