这是我尽力给出的最小示例,但它仍然有点长且复杂。
我创建了一个 RMarkdown,它使用 Pandoc 和 LaTeX 生成汽车数据集的 PDF。我希望第二列的宽度正好是 9 厘米。
---
title: "debug_colWidth"
output:
pdf_document:
includes:
in_header: "header.tex"
params:
fileName: ''
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo=FALSE, warning=FALSE, message=FALSE, comment=NA)
```
```{r packages, results='hide'}
pckgs <- c('knitr', 'kableExtra', 'tinytex')
for(pckg in pckgs){
if(!pckg %in% installed.packages()[, 'Package']) {
install.packages(pckg, repos='http://cran.us.r-project.org')
}
require(pckg, character.only=TRUE)
}
```
```{r}
knitr::kable(cars, booktab=TRUE, longtable=TRUE, format="latex") %>%
kableExtra::column_spec(2, width="9cm") %>%
kableExtra::row_spec(seq(1, nrow(cars), 1), hline_after=TRUE)
```
使用名为 debug_colWidth_run.R 的包装器 R 脚本,我可以根据需要多次迭代渲染,并为每次迭代指定不同的输出文件名:
pckgs <- c('rmarkdown', "stringr")
for(pckg in pckgs){
if(!pckg %in% installed.packages()[, 'Package']) {
install.packages(pckg, repos='http://cran.us.r-project.org')
}
suppressMessages(require(pckg, character.only=TRUE))
}
arg <- commandArgs(trailingOnly=TRUE)
fileNames <- strsplit(arg[1], "|", fixed=TRUE)[[1]]
for (name in fileNames) {
rmarkdown::render(
"debug_colWidth.Rmd",
param = list(fileName=name),
output_file = paste(name, '.pdf', sep = '')
)
}
只要我与 markdown 和包装器脚本位于同一目录中,bash 调用就会像这样:
Rscript "debug_colWidth_run.R" "cars1|cars2"
第一次迭代运行良好,cars1.pdf 成功渲染。但是,cars2.pdf 无法从 Pandoc 输出的 .tex 文件渲染。错误消息:
! Undefined control sequence.
<argument> r>{\raggedleft \arraybackslash
}p{9cm}
l.84 ...ble}{r>{\raggedleft\arraybackslash}p{9cm}}
Pandoc 的输出 LaTeX 行是\begin{longtable}{r>{\raggedleft\arraybackslash}p{9cm}}
。此 LaTeX 行在第一次迭代中运行良好,所以我不知道为什么它会在第二次迭代中失败。如果我kableExtra::column_spec()
在原始 RMarkdown 中注释掉函数调用,一切也会运行良好,我可以进行任意多次迭代。
在 bash 中,Rscript "debug_colWidth_run.R" "cars2"
也运行良好。似乎无论出于什么原因,使用column_spec()
指定表格的列宽只会在我尝试迭代时中断。为什么会发生这种情况?
对于任何感兴趣的人,这是我的 header.tex:
\renewcommand*\familydefault{\sfdefault}
\usepackage{booktabs}
\usepackage{longtable}
\usepackage[hypertexnames=false]{hyperref}