Shiny progress bar from a global variable

匆匆过客 提交于 2021-02-08 06:23:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!