Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knitr: redirect chunk code output to terminal

I want to monitor some pretty lengthy parallelized computations embedded in a knitr file.

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.

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?

Sorry for not providing a minimal working example but I don't see how I could make one in this setting.

like image 955
Pepin_the_sleepy Avatar asked Nov 15 '13 19:11

Pepin_the_sleepy


People also ask

How do you show output in R Markdown in knitting?

Rendering Output There are two ways to render an R Markdown document into its final output format. If you are using RStudio, then the “Knit” button (Ctrl+Shift+K) will render the document and display a preview of it.

How do I hide code but show output in R Markdown?

include = FALSE prevents code and results from appearing in the finished file. R Markdown still runs the code in the chunk, and the results can be used by other chunks. echo = FALSE prevents code, but not the results from appearing in the finished file. This is a useful way to embed figures.

Which code chunk options enable you to display the output but hide the code in RMD?

Chunk options You use results="hide" to hide the results/output (but here the code would still be displayed). You use include=FALSE to have the chunk evaluated, but neither the code nor its output displayed.


1 Answers

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.

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

    ```{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

like image 78
Yihui Xie Avatar answered Oct 04 '22 00:10

Yihui Xie