Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible to show console messages (written with `message`) in a shiny ui?

Tags:

r

shiny

shinyjs

I don't understand R's message vs cat vs print vs etc. too deeply, but I'm wondering if it's possible to capture messages and show them in a shiny app?

Example: the following app can capture cat statements (and print statements as well) but not message statements

runApp(shinyApp(   ui = fluidPage(     textOutput("test")   ),   server = function(input,output, session) {     output$test <- renderPrint({       cat("test cat")       message("test message")     })   } )) 

Cross post from the shiny-discuss Google group since I got 0 answers.

like image 859
DeanAttali Avatar asked May 27 '15 06:05

DeanAttali


1 Answers

Yihui suggested I use withCallingHandlers, and that indeed let me to a solution. I wasn't quite sure how to use that function in a way that would do exactly what I needed because my problem was that I had a function that printed out several messages one at a time and using a naive approach only printed the last message. Here is the my first attempt (which works if you only have one message to show):

foo <- function() {   message("one")   message("two") }  runApp(shinyApp(   ui = fluidPage(     actionButton("btn","Click me"),     textOutput("text")   ),   server = function(input,output, session) {     observeEvent(input$btn, {       withCallingHandlers(         foo(),         message = function(m) output$text <- renderPrint(m$message)       )     })   } )) 

Notice how only two\n gets outputted. So my final solution was to use the html function from shinyjs package (disclaimer: I wrote that package), which lets me change or append to the HTML inside an element. It worked perfectly - now both messages got printed out in real-time.

foo <- function() {   message("one")   Sys.sleep(0.5)   message("two") }  runApp(shinyApp(   ui = fluidPage(     shinyjs::useShinyjs(),     actionButton("btn","Click me"),     textOutput("text")   ),   server = function(input,output, session) {     observeEvent(input$btn, {       withCallingHandlers({         shinyjs::html("text", "")         foo()       },         message = function(m) {           shinyjs::html(id = "text", html = m$message, add = TRUE)       })     })   } )) 
like image 69
DeanAttali Avatar answered Oct 07 '22 20:10

DeanAttali