如何在R Markdown中调用Shiny应用的output$元素生成报告
解决Shiny应用生成R Markdown报告时无法调用output对象的方法
核心原因:R Markdown渲染进程与Shiny运行环境相互独立,无法直接访问Shiny的output命名空间,也不能直接调用Shiny的input、响应式变量,所有依赖内容都需要通过传参的方式注入Rmd。
步骤1:重构Shiny侧的绘图逻辑,复用代码
把原来写在output$heatmap_hc里的绘图逻辑抽成独立的响应式表达式,同时供Shiny界面和报告使用:
# Shiny server 内代码 server <- function(input, output, session) { # 抽出生成热图的逻辑为响应式表达式 get_heatmap <- reactive({ # 此处粘贴你原来写在renderHighcharter({})内部的所有绘图代码 }) # 保留Shiny界面的输出,供应用内展示 output$heatmap_hc <- renderHighcharter({ get_heatmap() }) # 其他原有逻辑... }
步骤2:修改R Markdown的YAML头部,声明接收参数
在你的Rmd文件开头的YAML区块增加params字段,声明所有需要从Shiny传入的变量:
--- output: html_document params: score1_val: NA check11_val: NA check_report_val: NA prov11_prev_val: NA text_c_11_val: NA weight11_val: NA heatmap_obj: NA ---
步骤3:改写Rmd内的变量引用方式
把Rmd内所有直接引用Shinyinput、响应式值、output的地方,都改成引用params下的对应变量:
- 章节得分处:把
r score1()改为r params$score1_val - 表格行逻辑处:把所有
input$xxx、xxx()的引用改为params对应变量 - 热图展示处:把报错的
r output$heatmap_hc改为r params$heatmap_obj
修改后的对应部分示例:
>## <span style="color:#702080"> Section 1: `r params$score1_val` / 174 </span> <span style="color:#c110a0;text-align:center">Policy Check </span> | <span style="color:#c110a0;text-align:center">Provision</span> | <span style="color:#c110a0;text-align:center">Comment/Recommendation</span> | <span style="color:#c110a0;text-align:center">Weight</span> :--------- | :-------------------: | :-----------------: | ---: `r if(params$check11_val %in% params$check_report_val){ fluidRow(style = "border-top: 1px solid; border-color: #A9A9A9; padding-top: 10px;padding-bottom: 10px;",column(2, params$check11_val, style = align_center), column(4, params$prov11_prev_val, style = align_justify ), column(5, params$text_c_11_val), column(1, params$weight11_val, style = align_center) )} else{}` >## <span style="color:#702080"> Heat Map </span> `r params$heatmap_obj`
步骤4:在Shiny侧调用Rmd渲染时传入所有参数
在你Shiny中触发报告生成的逻辑(一般是downloadHandler)里,通过params参数把所有需要的变量传入Rmd:
# Shiny server 内的下载报告逻辑 output$download_report <- downloadHandler( filename = function() { "DO_liability_analysis.html" }, content = function(file) { rmarkdown::render( input = "你的Rmd文件路径.Rmd", output_file = file, params = list( score1_val = score1(), check11_val = input$check11, check_report_val = input$check_report_, prov11_prev_val = prov11_prev(), text_c_11_val = input$text_c_11, weight11_val = weight11(), heatmap_obj = get_heatmap() ), envir = new.env(parent = globalenv()) ) } )
注意事项
- 交互类图表(highcharter、plotly、leaflet等)直接传生成的htmlwidget对象即可,Rmd渲染为HTML格式时会自动保留交互能力
- 如果需要生成PDF/Word格式报告,交互类图表需要提前转为静态图片传入,比如用
plotly::export()、htmlwidgets::saveWidget()配合截图工具转换
内容的提问来源于stack exchange,提问作者Carlos Tellez
相关产品推荐
相关产品推荐

