我不太了解R的消息vs cat vs print vs等,但我想知道是否有可能捕获消息并在闪亮的应用程序中显示它们?
示例:以下应用程序可以捕获cat语句(以及print语句)但不捕获消息语句
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.
Yihui建议我使用withCallingHandlers
,这确实让我找到了解决方案。我不太确定如何以一种完全符合我需要的方式使用该功能,因为我的问题是我有一个函数可以一次打印几条消息并使用简单的方法只打印最后一条消息。这是我的第一次尝试(如果您只显示一条消息,则可以使用):
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)
)
})
}
))
请注意如何只输出two\n
。所以我的最终解决方案是使用html
包中的shinyjs
函数(免责声明:我编写了该包),它允许我更改或附加到元素内的HTML。它工作得很好 - 现在这两条消息都是实时打印出来的。
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)
})
})
}
))
我知道这不是那么优雅,但我使用capture.output
解决了类似的问题;遗憾的是sink
不允许同时捕获消息和输出。您没有按原始顺序获取它们,但您可以至少提取两个流(此处转为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>")
)})
})
)
输出:
test message
test message2
test cat
test cat2
也许在用户想要同时捕获它们但也将它们分开的情况下,这将提供方便的解决方法。 (你的shinyjs
包看起来很整洁,需要看看它!)