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

Shiny技术问题:如何从模块导出多类输出并传入报告?

问题分析与解决

报错原因

你遇到的unused argument (plotList = getPlot)错误,是因为**download_server函数定义的第二个参数是myplot,但调用时传入了未在函数定义中声明的plotList参数**,参数名不匹配导致报错。

核心问题梳理

  1. 模块参数不匹配:下载模块的参数定义与调用时的参数名不一致
  2. 多绘图对象传递未正确处理:plot_server返回的是包含两个reactive绘图对象的列表,但下载模块未正确提取和使用这些对象
  3. 细节错误:代码中存在文件名拼写错误(myRport.Rmd应为myReport.Rmd),且Rmd参数仅传递了单个绘图

修正后的完整代码

Shiny 应用代码

library(shiny)
library(ggplot2)
library(rmarkdown)

# 绘图模块 UI
plot_ui <- function(id) {
  ns <- NS(id)
  tagList(
    plotOutput(ns("plot1")),
    plotOutput(ns("plot2"))
  )
}

# 绘图模块 Server
plot_server <- function(id) {
  moduleServer(id, function(input, output, session) {
    myplot1 <- reactive({
      ggplot(mtcars, aes(wt, mpg)) +
        geom_point() +
        labs(title = "MPG vs Weight")
    })
    myplot2 <- reactive({
      ggplot(mtcars, aes(wt, drat)) +
        geom_point() +
        labs(title = "Rear Axle Ratio vs Weight")
    })
    
    output$plot1 <- renderPlot({ myplot1() })
    output$plot2 <- renderPlot({ myplot2() })
    
    # 返回包含两个reactive绘图的列表
    return(list(plot1 = myplot1, plot2 = myplot2))
  })
}

# 下载模块 UI
download_ui <- function(id) {
  ns <- NS(id)
  downloadButton(ns("report_button"), "Generate Report")
}

# 下载模块 Server(修正参数定义为plotList)
download_server <- function(id, plotList) {
  moduleServer(id, function(input, output, session){
    output$report_button <- downloadHandler(
      filename = "report.html",
      content = function(file) {
        # 修正文件名拼写错误
        tempReport <- file.path(tempdir(), "myReport.Rmd")
        file.copy("myReport.Rmd", tempReport, overwrite = TRUE)
        
        # 传递两个绘图参数(注意要调用reactive对象,加())
        params <- list(
          plot1 = plotList$plot1(),
          plot2 = plotList$plot2()
        )
        
        rmarkdown::render(
          tempReport,
          output_file = file,
          params = params,
          envir = new.env(parent = globalenv())
        )
      }
    )
  })
}

# 主应用
app_ui <- function() {
  fluidPage(
    plot_ui("plot_ui_1"),
    download_ui("download_ui_2")
  )
}

app_server <- function(input, output, session) {
  # 接收绘图模块返回的列表
  getPlot <- plot_server("plot_ui_1")
  # 调用下载模块时传入plotList参数,与函数定义匹配
  download_server("download_ui_2", plotList = getPlot)
}

shinyApp(app_ui, app_server)

对应的 myReport.Rmd 文件内容

---
title: "Multi-Plot Report"
output: html_document
params:
  plot1: NULL
  plot2: NULL
---

## 绘图1: MPG vs Weight
`r params$plot1`

## 绘图2: Rear Axle Ratio vs Weight
`r params$plot2`

关键代码解释

  1. 模块参数匹配:将download_server的参数从myplot改为plotList,与调用时的plotList = getPlot一致,解决参数不匹配问题。
  2. Reactive对象调用:在传递参数给Rmd时,必须调用reactive对象(即plotList$plot1()),因为plot_server返回的是reactive函数,而非直接的绘图对象。
  3. 多参数传递:在params列表中同时传入两个绘图对象,确保Rmd能接收并渲染多个绘图。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:55:15