可以在闪亮的 ui 中显示控制台消息(用 `message` 编写)?

Posted

技术标签:

【中文标题】可以在闪亮的 ui 中显示控制台消息(用 `message` 编写)?【英文标题】:Possible to show console messages (written with `message`) in a shiny ui? 【发布时间】:2015-08-09 01:42:32 【问题描述】:

我不太了解 R 的 message vs cat vs print vs etc.,但我想知道是否可以捕获消息并在闪亮的应用程序中显示它们?

示例:以下应用可以捕获 cat 语句(也可以打印语句)但不能捕获消息语句

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.

【问题讨论】:

我猜你可以使用withCallingHandlers() 在 R 表达式中捕获消息,然后打印/捕获它们。 感谢一辉,我能用了,帮了大忙 【参考方案1】:

一辉建议我使用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 被输出。所以我的最终解决方案是使用shinyjs 包中的html 函数(免责声明:我编写了那个包),它可以让我更改或附加到元素内的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)
      )
    )
  
))

【讨论】:

我向您致敬,先生。 非常感谢。我有一个打印 message() 文本的函数。使用您的解决方案,我可以使用 HTML 标记编辑 shinyjs::html(id = "text", html... 行。 要在每条消息后添加换行符,您可以调整为shinyjs::html(id = "text", html = paste0(m$message, '&lt;br&gt;'), add = TRUE) @DeanAttali,是否可以将catprint 实时捕获到UI?如果某人的函数使用 cat 或 print,withCallingHandlerstryCatch 不起作用。 看来这只适用于observeEvent。我是否错过了一些可以在eventReactive 上工作的东西?【参考方案2】:

我知道这不是那么优雅,但我使用capture.output 解决了一个类似的问题;遗憾的是sink 不允许同时捕获 messageoutput。您没有按原始顺序获取它们,但您至少可以提取两个流(这里转为 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 包裹看起来很整洁,需要看一看!)

【讨论】:

这种方法的问题是所有的输出都在最后被打印出来,它不是实时的。因此,如果您运行一个在运行时打印输出的慢速函数,则在它完成之前您不会看到它

以上是关于可以在闪亮的 ui 中显示控制台消息(用 `message` 编写)?的主要内容,如果未能解决你的问题,请参考以下文章

闪亮的 Ui - 多次参考同一个情节

闪亮的不显示带有 HTML/JSON 错误消息的表格

R闪亮用消息替换空图

没有在闪亮的情节中显示情节

用户输入等表格的闪亮 UI 美学改进

反复在闪亮的renderTable中突出显示一行