注意:问题的主题和此答案已在xtable 1.8-2 中解决。
虽然该问题已通过解决方法自行回答,但我认为对于其他用户来说,一些详细信息可能会有所帮助。
会发生什么?
要了解此处发生的情况,我们需要仔细查看文档在从 RMD 到 PDF 的过程中所经历的转换步骤。步骤是:
RMD --> MD --> TEX --> PDF
让我们倒序查看文件:
-
TEX:(由MDpandoc生成)
% …
\{\footnotesize
\begin{tabular}{rrrr}
\hline
& X1 & X2 & X3 \\
\hline
1 & 1 & 3 & 5 \\
2 & 2 & 4 & 6 \\
\hline
\end{tabular}
\}
% …
-
MD(由RMDknitr生成)
---
output:
pdf_document:
keep_tex: yes
---
{\footnotesize
\begin{tabular}{rrrr}
\hline
& X1 & X2 & X3 \\
\hline
1 & 1 & 3 & 5 \\
2 & 2 & 4 & 6 \\
\hline
\end{tabular}
}
-
RMD:(源文件)
---
output:
pdf_document:
keep_tex: yes
---
```{r, results='asis', echo=FALSE}
library(xtable)
mytable <- xtable(data.frame(matrix(c(1:6), nrow = 2)))
print(mytable,
comment = FALSE,
floating = FALSE,
size = "footnotesize"
)
```
回想一下:问题是,PDF 中有可见的花括号。他们来自哪里?
- 它们是
TEX 文件(\{ 和 \})中转义大括号的结果。
- 这些花括号也存在于
MD 文件中,但它们没有被转义。
所以我们现在知道两件事:我们看到花括号是因为它们被转义了,它们被pandoc 转义了。
但是为什么这些花括号存在呢? print.xtable 在指定 size 时输出它们。目标是创建一个组并仅在该组内应用size。 (对于floating = TRUE,不需要按花括号进行分组,因为在figure 环境中设置了size。无论如何都会打印花括号。)
为什么pandoc 会转义这对花括号,但不会转义所有其他花括号(例如\begin{tabular})?这是因为pandoc 应该转义字面意思的特殊字符但留下raw LaTeX unescaped。但是,pandoc 不知道外部大括号是 LaTeX 命令而不是文本。
(floating = TRUE 不会出现问题,因为花括号位于被识别为 LaTeX 的 figure 环境中。)
解决方案
在了解了问题之后,我们能做些什么呢?一种解决方案已经是posted by the OP:避免在print.xtable 中指定size 并手动插入footnotesize 命令:
---
output:
pdf_document:
keep_tex: yes
---
```{r, results='asis', echo=FALSE}
library(xtable)
mytable <- xtable(data.frame(matrix(c(1:6), nrow = 2)))
cat("\\begin{footnotesize}")
print(mytable,
comment = FALSE,
floating = FALSE
)
cat("\\end{footnotesize}")
```
但是,从长远来看,如果xtable(当前版本:1.8-0)生成在pandoc 转换后仍然存在的 LaTeX 代码,那就太好了。这很简单:print.xtable 检查是否设置了size,如果设置了,则在大小规范之前插入{,在表格末尾插入}:
if (is.null(size) || !is.character(size)) {
BSIZE <- ""
ESIZE <- ""
}
else {
if (length(grep("^\\\\", size)) == 0) {
size <- paste("\\", size, sep = "")
}
BSIZE <- paste("{", size, "\n", sep = "")
ESIZE <- "}\n"
}
这个小修改将{ 替换为\begingroup 和} 替换为\endgroup:
if (is.null(size) || !is.character(size)) {
BSIZE <- ""
ESIZE <- ""
}
else {
if (length(grep("^\\\\", size)) == 0) {
size <- paste("\\", size, sep = "")
}
BSIZE <- paste("\\begingroup", size, "\n", sep = "")
ESIZE <- "\\endgroup\n"
}
对于 LaTeX,这没有什么区别,但是当 pandoc 识别 \begingroup(与 { 相对)它应该可以解决问题。我在xtable 中报告了这个as a bug,希望这个问题会在以后的版本中得到解决。