10

我想监视嵌入在 knitr 文件中的一些相当冗长的并行计算。

计算依赖于我编写的包,相关函数使用 mclapply 来自多核包中的 mclapply 进行并行化。此函数使用utils包中的txtProgressBar的稍微修改的实现输出进度条以监视计算进度。每次mclapply迭代完成时,进度条都会打印到终端并通过 fifo 连接进行更新。

这在从文件中获取或直接调用函数时工作正常,但我找不到让它在 knitr 中工作的方法。我已经尝试了相关的块选项,我可以将消息和警告重定向到终端,但不能重定向到进度条。任何人都可以帮忙吗?

很抱歉没有提供一个最小的工作示例,但我不知道如何在此设置中制作一个。

4

2 回答 2

8

因为txtProgressBar()写入标准输出,并knitr捕获标准输出中的所有内容,所以目前如果它是基于文本的并写入标准输出,则显示进度条并不容易。也许我可以在evaluate::evaluate(debug = TRUE)内部使用来实现你想要的,但我不完全确定这是否适用于文本进度条。

我目前的建议是:

  • 使用基于 GUI 的进度条,例如tcltk::tkProgressBar()
  • 将进度写入其他地方,例如(ab)使用stderr

    ```{r progress}
    pb = txtProgressBar(min = 0, max = 100, file = stderr())
    for (i in 1:100) {
      setTxtProgressBar(pb, i)
      Sys.sleep(0.05)
    }
    close(pb)
    ```
    
  • 或在代码块之外使用您的函数,例如在内联表达式中(例如\Sexpr{my_multicore_function()}在 Rnw 或`r my_cool_fun()`Rmd 中),因为内联评估不会捕获标准输出

于 2013-11-16T21:20:05.537 回答
1

在阅读了 Yihui 的回答中关于将进度条打印到 stderr 的观点后,我建议临时重定向stdoutstderrwith sink()

sink(stderr())

your_code()

sink()
于 2017-01-28T03:33:40.280 回答