I want to monitor some pretty lengthy parallelized computations embedded in a knitr file.
我想监视嵌入在knitr文件中的一些非常冗长的并行计算。
The computations rely on a package I have written, and the relevant function uses mclapply from the multicore package for parallelization. This function outputs progress bars to monitor the progress of the computations using a slightly modified implementation of txtProgressBar from the utils package. The progress bar is printed to the terminal and updated through a fifo connection every time an iteration of mclapply is complete.
计算依赖于我编写的包,相关函数使用多核包中的mclapply进行并行化。此函数使用utils包中稍微修改的txtProgressBar实现输出进度条以监视计算的进度。每当mclapply的迭代完成时,进度条将打印到终端并通过fifo连接进行更新。
This works fine when sourcing from a file or calling directly the function, but I find no way to get this to work within knitr. I have tried the relevant chunk options, I can get messages and warnings redirected to the terminal, but not the progress bar. Can anyone help?
当从文件中获取或直接调用该函数时,这样可以正常工作,但我发现无法在knitr中使用它。我已经尝试了相关的块选项,我可以将消息和警告重定向到终端,但不是进度条。有人可以帮忙吗?
Sorry for not providing a minimal working example but I don't see how I could make one in this setting.
很抱歉没有提供最小的工作示例,但我不知道如何在此设置中制作一个。
2 个解决方案
#1
6
Because txtProgressBar()
writes to stdout, and knitr
captures everything in stdout, so currently it is not easy to show your progress bar if it is text-based and writes to stdout. Perhaps I can use evaluate::evaluate(debug = TRUE)
internally to achieve what you want, but I'm not entirely sure if that works well with the text progress bar.
由于txtProgressBar()写到标准输出,并knitr捕获标准输出的一切,所以目前它是不容易表现出你的进度条,如果它是基于文本的,并写入到标准输出。也许我可以在内部使用evaluate :: evaluate(debug = TRUE)来实现你想要的,但我不完全确定它是否适用于文本进度条。
My suggestions at the moment are:
我目前的建议是:
- use a GUI-based progress bar like
tcltk::tkProgressBar()
-
write the progress to other places, e.g. (ab)using
stderr
将进度写入其他地方,例如(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) ```
-
or use your function outside a code chunk, e.g. in an inline expression (such as
\Sexpr{my_multicore_function()}
in Rnw or`r my_cool_fun()`
in Rmd), because inline evaluation does not capture stdout或者在代码块之外使用你的功能,例如在内联表达式中(例如Rnw中的\ Sexpr {my_multicore_function()}或Rmd中的`r my_cool_fun()`),因为内联评估不捕获stdout
使用基于GUI的进度条,如tcltk :: tkProgressBar()
#2
1
Having read the point about printing progress bar to stderr in Yihui's answer I would suggest temporary redirecting stdout
to stderr
with sink()
.
在Yihui的回答中读到有关打印进度条的问题后,我建议暂时将stdout重定向到带有sink()的stderr。
sink(stderr())
your_code()
sink()
#1
6
Because txtProgressBar()
writes to stdout, and knitr
captures everything in stdout, so currently it is not easy to show your progress bar if it is text-based and writes to stdout. Perhaps I can use evaluate::evaluate(debug = TRUE)
internally to achieve what you want, but I'm not entirely sure if that works well with the text progress bar.
由于txtProgressBar()写到标准输出,并knitr捕获标准输出的一切,所以目前它是不容易表现出你的进度条,如果它是基于文本的,并写入到标准输出。也许我可以在内部使用evaluate :: evaluate(debug = TRUE)来实现你想要的,但我不完全确定它是否适用于文本进度条。
My suggestions at the moment are:
我目前的建议是:
- use a GUI-based progress bar like
tcltk::tkProgressBar()
-
write the progress to other places, e.g. (ab)using
stderr
将进度写入其他地方,例如(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) ```
-
or use your function outside a code chunk, e.g. in an inline expression (such as
\Sexpr{my_multicore_function()}
in Rnw or`r my_cool_fun()`
in Rmd), because inline evaluation does not capture stdout或者在代码块之外使用你的功能,例如在内联表达式中(例如Rnw中的\ Sexpr {my_multicore_function()}或Rmd中的`r my_cool_fun()`),因为内联评估不捕获stdout
使用基于GUI的进度条,如tcltk :: tkProgressBar()
#2
1
Having read the point about printing progress bar to stderr in Yihui's answer I would suggest temporary redirecting stdout
to stderr
with sink()
.
在Yihui的回答中读到有关打印进度条的问题后,我建议暂时将stdout重定向到带有sink()的stderr。
sink(stderr())
your_code()
sink()