R语言 如何使函数的打印结果在Shiny应用程序中对用户可见

R语言 如何使函数的打印结果在Shiny应用程序中对用户可见

问题描述

我正在使用pso R包中的psoptim()函数。该函数对算法的每次迭代生成一个打印结果,我希望这些输出对Shiny应用程序用户可见。

这是一个显示算法打印结果的示例:

library(pso)
psoptim(rep(NA,2),function(x) 20+sum(x^2-10*cos(2*pi*x)),lower=-5,upper=5,control=list("fnscale" = -1, "trace" = 1, "maxit" = 60, "REPORT" = 1))

这是我迄今为止尝试过的,但没有取得任何成功:

library(shiny)
library(pso)

withConsoleRedirect <- function(containerId, expr) {
  # Change type="output" to type="message" to catch stderr
  # (messages, warnings, and errors) instead of stdout.
  txt <- capture.output(results <- expr, type = "output")
  if (length(txt) > 0) {
    insertUI(paste0("#", containerId), where = "beforeEnd",
             ui = paste0(txt, "\n", collapse = "")
    )
  }
  results
}

# Example usage

ui <- fluidPage(
  actionButton("run_optim", "Run"),
  pre(id = "console")
)

server <- function(input, output, session) {
  observeEvent("run_optim",{
    #invalidateLater(1000)

    withConsoleRedirect("console", {
      psoptim(rep(NA,2),function(x) 20+sum(x^2-10*cos(2*pi*x)),lower=-5,upper=5,control=list("fnscale" = -1, "trace" = 1, "maxit" = 60, "REPORT" = 1))
    })
  })
}

shinyApp(ui, server)

解决方案

编辑 : pso::psoptim 正在使用 message(..) (基于 https://github.com/cran/pso/blob/master/R/psoptim.R#L83 ),因此我们需要告诉 capture.output 捕获消息而不是打印/输出。

请尝试这个变体:

doSomething <- function(...) message("hello world: ", sample(100, 1), "\n")
withConsoleRedirect <- function(textAreaId, expr, session = getDefaultReactiveDomain()) {
  txt <- capture.output(res <- expr, type = "message")
  if (length(txt) && any(nzchar(txt))) {
    oldtxt <- sessioninput[[textAreaId]]
    if (!nzchar(oldtxt[1])) oldtxt <- oldtxt[-1]
    updateTextAreaInput(session, textAreaId,
                        value = paste(trimws(c(oldtxt, txt)), collapse = "\n"))
  }
  res
}
library(shiny)
ui <- fluidPage(
  shinyjs::useShinyjs(),
  actionButton("btn", "Run"),
  shinyjs::disabled(textAreaInput("console", "Console", rows = 5)),
  actionButton("clr", "Clear text area")
)
server <- function(input, output, session) {
  observeEvent(inputbtn, {
    withConsoleRedirect("console", {
      doSomething()
    })
  })
  observeEvent(input$clr, {
    updateTextAreaInput(session, "console", value = "")
  })
}
shinyApp(ui, server)

R语言 如何使函数的打印结果在Shiny应用程序中对用户可见

在这个示例中,我建议使用一个 textarea HTML输入元素来显示文本。由于在这种情况下我不希望用户能够添加任何内容,我使用了 shinyjs 包来禁用它(不允许用户输入),尽管这不是你要求的机制所必须的。

由于这是一个始终添加的元素,我提供了清除文本区域的功能。

如果这可能是一个长时间运行的操作,很容易看出在每个消息之前添加一个时间戳(尽管在这种情况下,您可能选择使用 future 或其他后台处理能力,以便您的shiny app不会冻结)。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程