R Shiny导出R Sweave报告输出与应用内结果不一致问题求助
问题根因
- 导出报告的knit进程与Shiny会话是独立运行的,你当前的Sweave文件直接调用Shiny服务端定义的响应式函数(
VIF()/aic()等),knit进程根本无法访问这些Shiny上下文里的对象,只会读取工作目录下历史运行遗留的同名对象,导致输出旧结果或报错。 - Sweave文件中给代码块设置了
cache=TRUE,会缓存首次运行的结果,后续导出报告时不会重新计算最新值,直接调用缓存内容。 - 你在
Reg.fit响应式函数中写的saveRDS(fit, "Model.rds")位于return(fit)之后,代码永远不会执行,也无法通过读取本地模型文件的方式传递结果。
修复步骤
1. 修改Shiny服务端逻辑
调整Reg.fit响应式函数
把模型保存代码移到return之前,确保能正常落地模型文件:
Reg.fit = reactive({ if (is.null(input$IndepVar)){ return(NULL) } data1 = datos() if (input$Txdef == "dlog"){ if (nrow(data1[data1[input$DepVar] <= 0,]) > 0){ data1[data1[input$DepVar] <=0,input$DepVar] = 1e-5} } data1[input$DepVar] = lapply(data1[input$DepVar],as.numeric) e1 = Reg.model() fit = lm(formula(e1),data = data1) saveRDS(fit, "Model.rds") # 移到return前才会执行 return(fit) } )
调整downloadHandler导出逻辑
提前把所有报告需要的响应式结果求值,直接传递给knit的运行环境:
output$report = downloadHandler( filename = 'myreport.pdf', content = function(file) { tempReport <- file.path(tempdir(), "sf.Rnw") file.copy("sf.Rnw", tempReport, overwrite = TRUE) # 提前把所有需要的响应式结果转为普通变量,传递给knit环境 report_params <- list( textReg = textReg(), Reg.model = Reg.model(), SummaryReg = SummaryReg(), aic = aic(), VIF = VIF(), Determination = Determination(), AdjustedDetermination = AdjustedDetermination(), testanalitico2 = testanalitico2(), concprueba2 = concprueba2() ) out = knit2pdf(tempReport, clean = TRUE, envir = list2env(report_params)) file.rename(out, file) }, contentType = 'application/pdf' )
2. 修改Sweave文件
关闭所有缓存,删除硬编码的固定路径设置,直接使用传递进来的普通变量:
\documentclass{article} \title{模型复现与验证报告} \begin{document} \maketitle <<setup, cache = FALSE, echo=FALSE>>= opts_chunk$set(width=200) # 删除固定路径setwd,避免临时目录路径不匹配报错 @ <<Concstat,echo=FALSE>>= library(knitr) options(digits=2) @ \section{回归模型} 模型复现结果: <<Model,echo=FALSE>>= # 所有cache参数设为FALSE,删除冗余的缓存配置 opts_chunk$set(comment="", message=FALSE,tidy.opts=list(keep.blank.line=TRUE, width.cutoff=120),options(width=100), cache=FALSE,fig.align='center',fig.height=6, fig.width=10,fig.path='figure/beamer-',fig.show='hold',size='footnotesize') print(textReg) print(Reg.model) print(SummaryReg) @ 模型结论: AIC值: <<echo=FALSE>>= print(aic) @ VIF值: <<echo=FALSE>>= print(VIF) @ 参数显著性结论: <<echo=FALSE>>= print(Determination) @ 调整R平方: <<Vif,echo=FALSE>>= print(AdjustedDetermination) @ 模型复现完成后进入验证环节,检验线性模型假设: \subsection{残差正态性检验} <<nor,echo=FALSE>>= print(testanalitico2) print(concprueba2) @ \end{document}
3. 额外注意事项
- 不要在Shiny运行过程中手动修改工作目录,避免knit读取文件路径错误
- 如果需要多次导出不同参数的报告,建议每次导出时给生成的中间文件加唯一后缀,避免不同会话的文件相互覆盖
内容的提问来源于stack exchange,提问作者Maria Ruxandra
相关产品推荐
相关产品推荐

