Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

real-time printing to console with R in jupyter

Using an R GUI or just R from a command line, this code results in integers being printed 0.2 seconds apart.

In contrast when I use R in a jupyter notebook, all of the printing happens only after the loop is complete.

for(x in 1:10){
    print(x)
    Sys.sleep(0.2)
}

I tried to force real-time printing inside of Jupyter with

for(x in 1:10){
    print(x)
    flush.console()
    Sys.sleep(0.2)
}

...to no effect. The results were the same -- printing from within a for loop in jupyter always seems to be delayed until after the loop.

Is there a way to ensure the notebook outputs the results of print statements in a real time way?

like image 866
Curt F. Avatar asked Jun 07 '16 21:06

Curt F.


3 Answers

Currently, the only way to "trigger" processing of printed output is either using message("text") (instead of print("text") or cat("text")) or not writing it into the loop but in a statement of it's own.

The underlying problem is in https://github.com/IRkernel/IRkernel/issues/3 and a proposed fix is in https://github.com/hadley/evaluate/pull/62 -> It needs a change in evaluate to allow flush.console() and friends to work. The gist of the problem: we use evaluate to execute the code and evaluate process the output one statement at a time and handles the output after the statement completes. Unfortunately, in this case, a for-loop is just one statement (as is everything in {...} blocks), so printed output only appears in the client after the for-loop is done.

A workaround is using the IRdisplay package and the display_...() functions instead of print()/cat() (or plots...). But this needs full control over the printed stuff: It's either everything is using print (and it gets delayed until after the complete statement is finished) or nothing should print (or plot) in that statement. If a called functions prints something, the output would be in the wrong order ({print("a"); display_text("b"); print("c")} would end up as b a c). Using capture.output() might get you around this limitation, if you really have to... If you use plots, there are currently no workarounds apart from writing the plot to disc and sending it via display_png(..) and friends.

like image 143
Jan Katins Avatar answered Oct 17 '22 05:10

Jan Katins


This is not an issue any more. The following code works in jupterLab now

for(x in 1:10){
    print(x)
    flush.console()
    Sys.sleep(0.2)
}
like image 25
David Chen Avatar answered Oct 17 '22 04:10

David Chen


R version of the answer for Python Flush output in for loop in Jupyter notebook works for me:

cat(paste0('Your text', '\r'))

Apparently \r will trigger a flush.

like image 32
Viktor Horváth Avatar answered Oct 17 '22 04:10

Viktor Horváth