如何让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
相关产品推荐
相关产品推荐

