You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让psoptim()的迭代打印输出在Shiny应用中展示给用户

在Shiny应用中实时展示psoptim的迭代输出

我正在使用R语言pso包中的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)

解决方案

原代码的问题在于capture.output会一次性捕获所有输出,无法实时展示迭代过程。我们可以利用psoptim自带的traceFun参数,自定义输出逻辑,实现实时更新:

library(shiny)
library(pso)

ui <- fluidPage(
  actionButton("run_optim", "运行PSO算法"),
  pre(id = "console_output", style = "white-space: pre-wrap; height: 300px; overflow-y: auto;")
)

server <- function(input, output, session) {
  observeEvent(input$run_optim, {
    # 清空历史输出
    session$sendCustomMessage(type = "clearConsole", message = "")
    
    # 自定义trace函数,实时推送输出到前端
    custom_trace <- function(txt) {
      session$sendCustomMessage(type = "appendConsole", message = paste0(txt, "\n"))
    }
    
    # 运行PSO算法,指定自定义trace函数
    psoptim(
      par = rep(NA, 2),
      fn = 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,
        traceFun = custom_trace  # 绑定自定义输出逻辑
      )
    )
  })
}

# 添加前端JS处理消息,实现实时更新
shinyApp(
  ui = tagList(
    ui,
    tags$script(HTML("
      Shiny.addCustomMessageHandler('appendConsole', function(message) {
        var consoleEl = document.getElementById('console_output');
        consoleEl.textContent += message;
        // 自动滚动到最新内容
        consoleEl.scrollTop = consoleEl.scrollHeight;
      });
      Shiny.addCustomMessageHandler('clearConsole', function() {
        document.getElementById('console_output').textContent = '';
      });
    "))
  ),
  server = server
)

关键说明

  • 借助psoptim的traceFun参数,将每次迭代的输出通过Shiny自定义消息转发到前端。
  • 前端JavaScript监听消息,实时追加内容到控制台容器,并自动滚动到底部,确保用户能看到最新的迭代日志。
  • 点击按钮时先清空历史输出,避免内容冗余。

内容的提问来源于stack exchange,提问作者Camilo Almario

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 05:07:39