print console output on shiny synchronously during the computing process

4,168 views
Skip to first unread message

Eric Hung

unread,
Apr 2, 2016, 4:42:12 PM4/2/16
to Shiny - Web Framework for R
Hello, I recently ran into a problem that as my computing took lots of time, I'd like to show the text output on shiny rather than progress bar or loading message. My function looked like

printText <- function() {
  for(i in 1:10){
    Sys.sleep(0.1)
    print(paste("My text", i))
    y = i + 1
  }
  return(y)
}


I can print it with verbatimTextOutput but I also need the returned value of y. For example,

runApp(list(
  ui = shinyUI(fluidPage(
    titlePanel("Print consol output"),
    sidebarLayout(
      sidebarPanel(actionButton("go", "Go")),
      mainPanel(
        verbatimTextOutput("text")
      )
    )
  )),
  server = shinyServer(function(input, output, session){
    observeEvent(input$go, {
      output$text <- renderPrint({
          y <- printText()
      })
    })
  })
))


The problem is that if I want to use the returned y I need to create a reactive object, which may take me 2 times longer because I execute printText() twice, while printing and pass to reactive object.


How could I get the value of y and print the text onto shiny without duplicated work? Notice that I'm not gonna use progress bar because my real function is not a loop actually. I don't know how many times it may repeat. What I want is to capture the text output during the process and pass the returned value to y without creating a reactive object that causes duplicated work.


Many thanks in advance!

Joe Cheng

unread,
Apr 2, 2016, 4:49:28 PM4/2/16
to Eric Hung, Shiny - Web Framework for R
Yeah, print() doesn't work inside renderPrint. However, cat(file=stderr(), message) should work.
--
You received this message because you are subscribed to the Google Groups "Shiny - Web Framework for R" group.
To unsubscribe from this group and stop receiving emails from it, send an email to shiny-discus...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/shiny-discuss/718b948f-89f9-4bce-9054-7ccbe6a6f049%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dean Attali

unread,
Apr 3, 2016, 2:49:10 AM4/3/16
to Shiny - Web Framework for R
I posted a solution to something similar to SO a while ago http://stackoverflow.com/questions/30474538/possible-to-show-console-messages-written-with-message-in-a-shiny-ui

In your case, something like this would work

printText <- function() {
  for(i in 1:10){
    Sys.sleep(0.1)
    shinyjs::html("text", paste("My text", i), add = TRUE)
    y = i + 1
  }
  return(y)
}

runApp(list(
  ui = shinyUI(fluidPage(
    shinyjs::useShinyjs(),
    titlePanel("Print consol output"),
    sidebarLayout(
      sidebarPanel(actionButton("go", "Go")),
      mainPanel(
        div(id = "text")
      )
    )
  )),
  server = shinyServer(function(input, output, session){
    observeEvent(input$go, {
      shinyjs::html("text", "")
      y <- printText()
    })
  })
))

Basically, it's using the shinyjs package to manually change the HTML inside the element, instead of using shiny's reactivity.  If you can get Joe's solution to work, that'd be better though

Eric Hung

unread,
Apr 3, 2016, 7:40:04 PM4/3/16
to Shiny - Web Framework for R
Thanks Dean. It works perfect in this case. But what should I do if I don't change my function? Because in my real function, I cannot find where

paste("My text", i)

is. Is it possible to make it without hacking the function? My real function is actually `applyStrategy` in quantstrat package. I can't find the code that prints the texts so I prefer not to change the function.

Many thanks again!


Dean Attali於 2016年4月3日星期日 UTC+8下午2時49分10秒寫道:
Reply all
Reply to author
Forward
0 new messages