让 Shiny 更新 ui 并在之后运行长时间计算

Posted

技术标签:

【中文标题】让 Shiny 更新 ui 并在之后运行长时间计算【英文标题】:Getting Shiny to update the ui and and run long calculation afterwards 【发布时间】:2016-03-17 13:23:52 【问题描述】:

我一直在尝试实现一个简单的界面来在 Shiny 上运行 R 脚本。我希望我的启动应用程序能够了解它正在对用户做什么,我能想象的更简单的事情是向用户宣布一些长时间的计算将在它实际执行之前开始,到目前为止我找不到方法强制服务器在计算开始之前将更新发送到 UI,并且 UI 被阻塞直到脚本结束。谁能看到一个简单的方法来纠正这个问题,还是我已经完全改变了我解决问题的方式?

感谢您的帮助

服务器.R

shinyServer(function(input, output, session) 

Exec = reactiveValues(stateTxt = "Not started", state = 0)

output$execStatus = renderText(Exec$stateTxt)
runCalc = function() 
    setwd(root) 
    Exec$stateTxt = "Calculating..."
    source("calc.R")       
    Exec$stateTxt = "Finished"


observeEvent(input$runCalc, runCalc())
)

ui.R

shinyUI(pageWithSidebar(
      # Application title
  headerPanel("Long Calculation"),

  sidebarPanel(
    actionButton("runCalc", "Run Calculation")
    ),

  mainPanel(verbatimTextOutput("execStatus"))


))

【问题讨论】:

【参考方案1】:

不是 100% 你想做的,但你可以使用withProgress() 函数向用户显示一个注释以进行长时间的计算:

library(shiny)

server <- function(input, output) 
  runCalc = function() 
    withProgress(message = 'Please stand by...', value = 1, 
      Sys.sleep(3)
      output$execStatus <- renderText("Calculation finished")
      )
  
  observeEvent(input$runCalc, runCalc())
  

ui <- pageWithSidebar(
  headerPanel("Long Calculation"), 
  sidebarPanel(
    actionButton("runCalc", "Run Calculation")
  ),  
  mainPanel(verbatimTextOutput("execStatus"))
)

shinyApp(server=server, ui=ui)

这样,您还可以增加进度条,从而提高易用性:

  runCalc = function() 
    withProgress(message = 'Please stand by...', min=0, max=1, 
      Sys.sleep(1)
      incProgress(0.3)
      Sys.sleep(1)
      incProgress(0.3)
      Sys.sleep(1)
      incProgress(0.3)
      output$execStatus <- renderText("Calculation finished")
      )
  

【讨论】:

以上是关于让 Shiny 更新 ui 并在之后运行长时间计算的主要内容,如果未能解决你的问题,请参考以下文章

Javascript Promises库在浏览器中制作“长时间运行代码 - 非阻塞UI”?

具有长时间运行计算的 Django 应用程序

当一个线程完成任务而另一个线程正在运行时,有没有办法更新 Web 表单 UI

长时间运行的任务阻塞了 UI

WinForm 应用程序 UI 在长时间运行期间挂起

WinForm 应用程序 UI 在长时间运行期间挂起