Knitr:将块码输出重定向到终端

时间:2013-11-15 19:34:29

标签: r multicore knitr fifo mclapply

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

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

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

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

2 个答案:

答案 0 :(得分:7)

因为txtProgressBar()写入stdout,而knitr捕获stdout中的所有内容,所以目前要显示进度条并不容易,如果它是基于文本的并写入stdout。也许我可以在内部使用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)
    ```
    
  • 或在代码块之外使用您的功能,例如在内联表达式中(例如Rnw中的\Sexpr{my_multicore_function()}或Rmd中的`r my_cool_fun()`),因为内联评估不捕获stdout

答案 1 :(得分:1)

在Yihui的回答中读到关于打印进度条到stderr的观点我建议暂时将stdout重定向到stderr sink()

sink(stderr())

your_code()

sink()