Knitr循环中无法打印绘图:PDF报告生成故障排查
解决方案
问题根源
你遇到的Missing $ inserted错误,是因为在results='asis'代码块中打印ggplot对象时,knitr输出了Markdown格式的图片引用(),而LaTeX编译器会把其中的下划线_识别为数学符号,导致语法错误;同时直接打印绘图的方式也无法在循环的动态页面中正确渲染。
修正后的代码
首先确保加载所需包:
library(survival) library(ggsurvminer) library(knitr) library(kableExtra)
然后修改newslide函数和循环逻辑:
#```{r config, include=FALSE} newslide <- function(content) { code <- deparse(substitute(content)) cat(sep = "\n", knitr::knit_child( quiet = TRUE, text = c("```{r dpi=600, warning=FALSE, message=FALSE, echo=FALSE}", code, "```") ) ) } #``` #```{r latex, echo=FALSE, results = 'asis'} plot_list <- list() category <- c("A","B","C") # 预先生成并存储ggplot对象 for (cat in category){ fit <- survfit(Surv(time, status) ~ sex, data = lung) p <- ggsurvplot(fit, data = lung) plot_list[[cat]] <- p$plot # 仅保留ggplot绘图部分 } # 循环生成每页内容 for (cat in category){ plot1 <- plot_list[[cat]] # 生成适配双栏的LaTeX表格 table1_latex <- kable(head(lung), format = "latex", booktabs = TRUE) %>% kable_styling(latex_options = c("hold_position", "scale_down")) newslide( content = { cat("\\begin{multicols}{2}\n") cat("\\noindent\n") cat(table1_latex) cat("\\columnbreak\n") print(plot1) # knitr会自动将ggplot转为LaTeX格式的图片 cat("\\end{multicols}\n") } ) } #```
关键调整点
- 移除子代码块的
results='asis':原函数中knit_child内的代码块使用了results='asis',导致绘图输出Markdown语法。移除后,knitr会自动将ggplot对象转为LaTeX的\includegraphics代码,适配PDF输出。 - 仅存储纯ggplot对象:
ggsurvplot返回的是包含多个元素的列表,仅提取$plot部分即可,避免多余元素干扰渲染。 - 表格适配双栏布局:使用
kable_styling的scale_down选项让表格自动缩小以适应双栏宽度,hold_position确保表格位置稳定。 - 简化LaTeX环境输出:直接在content中用
cat输出双栏环境的LaTeX代码,配合knitr对绘图的原生处理,确保页面结构正确。
内容的提问来源于stack exchange,提问作者carolinasc
相关产品推荐
相关产品推荐

