R Markdown循环中multicol环境下表格与图表排版问题求助
title: "Untitled"
header-includes:
- \usepackage{multicol}
- \usepackage[labelformat = empty]{caption}
output:
pdf_document:
keep_tex: true
```{r cars, echo=FALSE, results='asis'} library(ggplot2) tables1 <- list() tables2 <- list() tables3 <- list() tables4 <- list() plots1 <- list() plots2 <- list() plots3 <- list() categories <- c("A","B","C") for (cat in categories){ tables1[[cat]] <- head(iris) tables2[[cat]] <- head(cars) tables3[[cat]] <- head(mtcars) tables4[[cat]] <- head(ToothGrowth) plots1[[cat]] <- ggplot(cars) plots2[[cat]] <- ggplot(mtcars) plots3[[cat]] <- ggplot(ToothGrowth) } for (cat in categories){ table1 <- tables1[[cat]] table2 <- tables2[[cat]] table3 <- tables3[[cat]] table4 <- tables4[[cat]] plot1 <- plots1[[cat]] plot2 <- plots2[[cat]] plot3 <- plots3[[cat]] #then i format all the tables with kableExtra, removing the "table" enviroment cat("\\newpage\n") #a page for each category, containing all the plots and tables in the same order cat("\\fontsize{11}{13}\\selectfont\n") cat(cat, "\n") #title should be the name of the category cat("\\vspace*{-0.1cm}\\n\\n") print(table1) #full-width table cat("\\setlength{\\columnsep}{25pt}\\n") #full-width header cat("\\begin{multicols}{2}\\n") print(table2) cat("\\columnbreak\\n") cat("\\begin{center}\\n") print(plot1) cat("\\end{center}\\n") cat("\\end{multicols}\\n") #full-width header cat("\\begin{multicols}{2}\\n") print(table3) cat("\\columnbreak\\n") cat("\\begin{center}\\n") print(plot2) cat("\\end{center}\\n") cat("\\end{multicols}\\n") #full-width header cat("\\begin{multicols}{2}\\n") print(table4) cat("\\columnbreak\\n") cat("\\begin{center}\\n") print(plot3) cat("\\end{center}\\n") cat("\\end{multicols}\\n") }
解决方法
核心问题是ggplot默认生成浮动figure环境,与multicol配合时会脱离预期位置。通过修改knitr图表输出选项、添加非浮动标题命令可解决:
1. 调整YAML依赖(可选增强)
保留原有包,可添加float包辅助位置控制:
--- title: "Untitled" header-includes: - \usepackage{multicol} - \usepackage[labelformat = empty]{caption} - \usepackage{float} output: pdf_document: keep_tex: true ---
2. 修改R代码块
在循环中临时取消图表浮动环境,用captionof添加标题,同时调整表格样式适配multicol:
library(ggplot2) library(kableExtra) # 初始化列表并格式化表格/图表 tables1 <- list() tables2 <- list() tables3 <- list() tables4 <- list() plots1 <- list() plots2 <- list() plots3 <- list() categories <- c("A","B","C") for (cat in categories){ tables1[[cat]] <- head(iris) %>% kbl() %>% kable_styling(full_width = FALSE, position = "left") tables2[[cat]] <- head(cars) %>% kbl() %>% kable_styling(full_width = FALSE, position = "left") tables3[[cat]] <- head(mtcars) %>% kbl() %>% kable_styling(full_width = FALSE, position = "left") tables4[[cat]] <- head(ToothGrowth) %>% kbl() %>% kable_styling(full_width = FALSE, position = "left") plots1[[cat]] <- ggplot(cars, aes(speed, dist)) + geom_point() + ggtitle("Plot 1") plots2[[cat]] <- ggplot(mtcars, aes(mpg, disp)) + geom_point() + ggtitle("Plot 2") plots3[[cat]] <- ggplot(ToothGrowth, aes(len, supp)) + geom_boxplot() + ggtitle("Plot 3") } # 循环生成每页内容 for (cat in categories){ table1 <- tables1[[cat]] table2 <- tables2[[cat]] table3 <- tables3[[cat]] table4 <- tables4[[cat]] plot1 <- plots1[[cat]] plot2 <- plots2[[cat]] plot3 <- plots3[[cat]] # 每页开头 cat("\\newpage\n") cat("\\fontsize{11}{13}\\selectfont\n") cat("\\textbf{", cat, "}\n", sep = "") cat("\\vspace*{-0.1cm}\n\n") # 全宽表格 print(table1) cat("\\vspace{0.5cm}\n") # 第一组:Table 2 + Plot 1 cat("\\setlength{\\columnsep}{25pt}\n") cat("\\begin{multicols}{2}\n") print(table2) cat("\\columnbreak\n") # 取消浮动环境,输出图表并添加标题 knitr::opts_current$set(fig.env = "", fig.pos = "", out.width = "100%") print(plot1) cat("\\captionof{figure}{", plot1$labels$title, "}\n", sep = "") cat("\\end{multicols}\n") cat("\\vspace{0.5cm}\n") # 第二组:Plot 2 + Table 3(匹配预期布局) cat("\\begin{multicols}{2}\n") knitr::opts_current$set(fig.env = "", fig.pos = "", out.width = "100%") print(plot2) cat("\\captionof{figure}{", plot2$labels$title, "}\n", sep = "") cat("\\columnbreak\n") print(table3) cat("\\end{multicols}\n") cat("\\vspace{0.5cm}\n") # 第三组:Table 4 + Plot 3 cat("\\begin{multicols}{2}\n") print(table4) cat("\\columnbreak\n") knitr::opts_current$set(fig.env = "", fig.pos = "", out.width = "100%") print(plot3) cat("\\captionof{figure}{", plot3$labels$title, "}\n", sep = "") cat("\\end{multicols}\n") }
关键修改说明
- 取消浮动环境:通过
knitr::opts_current$set(fig.env = "", fig.pos = "")让图表直接嵌入当前位置,不生成浮动figure。 - 添加图表标题:用
\captionof{figure}{标题}在multicol内添加标题,规避浮动环境限制。 - 表格适配:设置kable表格
full_width = FALSE和position = "left",避免在分栏内过宽。 - 间距优化:添加
\vspace调整元素间距,提升排版美观度。
内容的提问来源于stack exchange,提问作者carolinasc
相关产品推荐
相关产品推荐

