42

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

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

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

自从我得到 0 个答案以来,来自闪亮讨论的 Google 小组的交叉帖子。

4

2 回答 2

48

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)
      })
    })
  }
))
于 2015-05-27T18:45:37.023 回答
3

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

于 2016-11-21T01:01:42.213 回答