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

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")
    }
  )
}
#```

关键调整点

  1. 移除子代码块的results='asis':原函数中knit_child内的代码块使用了results='asis',导致绘图输出Markdown语法。移除后,knitr会自动将ggplot对象转为LaTeX的\includegraphics代码,适配PDF输出。
  2. 仅存储纯ggplot对象:ggsurvplot返回的是包含多个元素的列表,仅提取$plot部分即可,避免多余元素干扰渲染。
  3. 表格适配双栏布局:使用kable_styling的scale_down选项让表格自动缩小以适应双栏宽度,hold_position确保表格位置稳定。
  4. 简化LaTeX环境输出:直接在content中用cat输出双栏环境的LaTeX代码,配合knitr对绘图的原生处理,确保页面结构正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:43:17