5

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?

Curt F.
  • 4,452
  • 1
  • 20
  • 37
  • this is prbly worth posting an issue on [`IRKernel`](https://github.com/IRkernel/IRkernel). There are hacks for it in python but not R. – hrbrmstr Jun 07 '16 at 22:20
  • Thanks for the tip. I did file an issue. Afterwards, I found an [interesting related issue](https://github.com/IRkernel/IRkernel/issues/295) that recommends using `message()` instead of print. – Curt F. Jun 07 '16 at 23:26

3 Answers3

9

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.

Jan Katins
  • 2,059
  • 1
  • 21
  • 33
  • Thanks. It would be a "nice-to-have" to get this fixed but probably the most common use case is simply adding debugging or tracking statements to code blocks that are actively under development or that take a long time to run. For that use, `message()` works just fine. Getting plots to display in a certain order seems like a much less commonly-needed thing. – Curt F. Jun 08 '16 at 14:03
1

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.

1

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)
}
David Chen
  • 31
  • 3