2015-05-27 8 views
19

(Cross-Post von der glänzend-diskutieren Google-Gruppe seit ich 0 Antworten bekam).Möglich, Konsolenmeldungen (geschrieben mit `Nachricht`) in einem glänzenden ui zu zeigen?

Ich verstehe nicht R's Nachricht vs Katze vs Druck vs etc. zu tief, aber ich frage mich, ob es möglich ist, Nachrichten zu erfassen und wer sie in einer glänzenden App?

Beispiel: die folgenden App kann cat-Anweisungen (und print-Anweisungen als auch), aber nicht Nachricht Aussagen

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

Link zur ursprünglichen Frage erfassen: https://groups.google.com/forum/#!topic/shiny-discuss/UCacIquFJQY

Dank

+2

Ich denke, Sie können 'withCallingHandlers()' verwenden, um Nachrichten in einem R-Ausdruck zu erfassen, dann drucken/cat sie. –

+0

Danke Yihui, ich konnte das verwenden, das ist eine große Hilfe –

Antwort

24

Yihui schlug ich verwenden withCallingHandlers, und das ließ mich tatsächlich zu einer Lösung. Ich war mir nicht ganz sicher, wie ich diese Funktion so verwenden sollte, dass sie genau das tat, was ich brauchte. Mein Problem war, dass ich eine Funktion hatte, die mehrere Nachrichten nacheinander ausgab und die naive Methode nur die letzte Nachricht ausgab. Hier ist das mein erster Versuch (das funktioniert, wenn Sie nur eine Nachricht zu zeigen, haben):

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) 
    ) 
    }) 
    } 
)) 

Beachten Sie, wie nur two\n ausgegeben wird. So war meine letzte Lösung, die html Funktion von shinyjs Paket zu verwenden (Disclaimer: Ich schrieb dieses Paket), das ich an den HTML innerhalb eines Elements ändern oder anfügen kann. Es hat perfekt funktioniert - jetzt wurden beide Nachrichten in Echtzeit ausgedruckt.

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) 
     }) 
    }) 
    } 
)) 
+0

Ich tippe meinen Hut zu Ihnen, mein Herr. – geotheory

+0

Vielen Dank. Ich hatte eine Funktion, die Nachricht() Text gedruckt hat. Mit Ihrer Lösung kann ich die Zeile 'shinyjs :: html (id =" text ", html ...' mit HTML-Tags bearbeiten. – Facottons

0

Ich weiß, dass dies bei weitem nicht so elegant ist, aber ich arbeitete ein wenig herum ähnliches Problem mit capture.output; Leider sink ermöglicht keine gleichzeitige Erfassung von Nachricht s und Ausgabe obwohl. Man bekommt sie nicht in der ursprünglichen Reihenfolge, aber Sie können beide Ströme zumindest extrahieren (hier wandte sich an HTML):

runApp(shinyApp(
    ui = fluidPage(
    uiOutput("test") 
), 
    server = function(input,output, session) { 
    output$test <- renderUI({ 
     HTML(
     paste(capture.output(type = "message", expr = { 
     message(capture.output(type = "output", expr = { 
      cat("test cat<br>") 
      message("test message") 
      cat("test cat2<br>") 
      message("test message2") 
     })) 
     }), collapse="<br>") 
)}) 
}) 
) 

Ausgang:

test message 
test message2 
test cat 
test cat2 

Vielleicht in dem Fall, wenn der Benutzer möchte erfassen Sie beide, sondern trennen Sie sie auch, dies wird eine praktische Lösung bieten. (Ihr shinyjs Paket scheint ordentlich, müssen Sie einen Blick darauf werfen!)

+2

Das Problem bei diesem Ansatz ist, dass die gesamte Ausgabe am Ende gedruckt wird, aber nicht Wenn Sie eine langsame Funktion ausführen, die die Ausgabe druckt, während sie läuft, werden Sie sie erst sehen, wenn sie fertig ist –