r - 在并行 foreach 计算中使用标准 R Shiny 进度条

标签 r foreach shiny progress-bar doparallel

我正在尝试使用 doParallel 后端在并行 foreach 循环中使用标准 R Shiny 进度条。但是,这会导致以下错误消息:

Warning: Error in {: task 1 failed - "'session' is not a ShinySession object."

代码(最小工作示例)

library(shiny)
library(doParallel)

ui <- fluidPage(
  actionButton(inputId = "go", label = "Launch calculation")
)

server <- function(input, output, session) {

  workers=makeCluster(2)
  registerDoParallel(workers)

  observeEvent(input$go, {
    Runs=c(1:4)
    Test_out=foreach(i=Runs, .combine=cbind, .inorder=TRUE, .packages=c("shiny"),.export=c("session")) %dopar% { 
      pbShiny = shiny::Progress$new()
      pbShiny <- Progress$new(session,min = 0, max = 10)
      on.exit(pbShiny$close())
      test_vec=rep(0,100)

      for(i in 1:10){
        test_vec=test_vec+rnorm(100)
        pbShiny$set(message="Simulating",detail=paste(i),
                  value=i)
        Sys.sleep(0.2)
      }

    }
  })
}

shinyApp(ui = ui, server = server)

如果我顺序运行 foreach 循环(使用 registerDoSEQ()),代码就会运行。 有谁知道如何解决这个问题吗?

<小时/>

总体目标

  • 使用 doParallel 在并行 foreach 循环中向用户显示进度 后端 Shiny
  • 用户应了解 worker 的数量和 每个 worker 的进度和/或总体进度
<小时/>

以下链接下有类似的问题,但由于未提供工作示例而未得到解决:

Utilizing parallel foreach for progress bar in R Shiny

最佳答案

doParallel 包是并行包的扩展,如此处的文档所示。

https://cran.r-project.org/web/packages/doParallel/doParallel.pdf

阅读并行包的文档,我们发现它实现了 3 种不同的方法来实现并行性。请记住,R 是一种单线程语言。

  1. 一个新的 R session ,其中父进程与工作进程或子进程进行通信。
  2. 通过 fork
  3. 使用操作系统级别的工具

您可以在此处找到此信息,

https://stat.ethz.ch/R-manual/R-devel/library/parallel/doc/parallel.pdf

这样做的结果是子进程在完成计算并返回值之前无法与父进程通信。据我所知,这是。

因此,无法在工作进程内勾选进度条。

完全披露,我没有使用过 doParallel 包,并且有关 Shiny 的文档是有限的。

<小时/>

替代解决方案

有一个类似的包,但是有关于 Shiny 的大量文档。这些是 futurespromises 以及 ipc 包。 futurespromises 支持异步编程,而 ipc 支持进程间通信。为了给我们提供更多帮助,它还有一个 AsyncProgress() 函数。

这是一个我们同步勾选两个计数器的示例。

示例

library(shiny)
library(future)
library(promises)
library(ipc)

plan(multisession)


ui <- fluidPage(
  actionButton(inputId = "go", label = "Launch calculation")
)

server <- function(input, output, session) {

  observeEvent(input$go, {

    progress = AsyncProgress$new(message="Complex analysis")

    future({
      for (i in 1:15) {
        progress$inc(1/15)
        Sys.sleep(0.5)
      }

      progress$close()
      return(i)
    })%...>%
      cat(.,"\n")

    Sys.sleep(1)

    progress2 = AsyncProgress$new(message="Complex analysis")

    future({
      for (i in 1:5) {
        progress2$inc(1/5)
        Sys.sleep(0.5)
      }

      progress2$close()

      return(i)
    })%...>%
      cat(.,"\n")

    NULL
  })
}

shinyApp(ui = ui, server = server)

您的代码已调整

这是您编写的代码,稍加修改即可分离出许多异步进程。任何工作都可以在工作线程中执行,例如您创建并添加 rnorm 的向量。 (此处未显示)

library(shiny)
library(future)
library(promises)
library(ipc)

plan(multisession)

ui <- fluidPage(
  actionButton(inputId = "go", label = "Launch calculation")
)

server <- function(input, output, session) {

  observeEvent(input$go, {
    Runs=c(1:4) #define the number of runs
    progress = list() #A list to maintain progress for each run

    for(j in Runs){
      progress[[j]] = AsyncProgress$new(message="Complex analysis")
      future({
        for (i in 1:10) {
          progress[[j]]$inc(1/10)
          Sys.sleep(0.2)
        }
        progress[[j]]$close()
        return(i)
    })%...>%
        cat(.,'\n')
    }

    NULL
  })
}

shinyApp(ui = ui, server = server)

上面的代码是在 ipc 文档中找到的代码的修改版本:

http://htmlpreview.github.io/?https://github.com/fellstat/ipc/blob/master/inst/doc/shinymp.html

其他资源:

https://rstudio.github.io/promises/articles/overview.html

关于r - 在并行 foreach 计算中使用标准 R Shiny 进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54532486/

相关文章:

java - 使用 foreach 迭代 List 时如何修复 ConcurrentModificationException?

r - 单击 map 后,ObserveEvent 不会打印出图层 ID

r - loadNamespace(name): there is no package called ‘Rcompression’ 中的错误

r - 如何向向量字符串添加多个后缀

javascript - 为什么这个函数总是返回 null

php - XML 到数据库 - foreach 循环到 MySQL

r - 无法使 Shiny 模块与 valueBox 一起使用

r - 侧栏中 Shiny 的调整按钮位置

R:为一天中的时间数据分配正确的日期

r - 使用 Tidyverse 检查该值是否存在于任何其他列中