在指定大小时使用 xtable 和 knitr 时额外的花括号

Extra curly braces when using xtable and knitr, after specifiying size

我正在使用 knitr 创建 R Markdown 文档,但 运行 在使用 xtable 创建 table 时遇到了麻烦。我的 table 非常大,我正在尝试使用 print 语句中的 size 命令减小大小。我 运行 遇到的问题是该命令似乎添加了两个额外的花括号,它们出现在 PDF 中,一个在 table 之前,一个在

之后。

有谁知道解决这个问题的方法吗?

MWE:

---
output:
  pdf_document:
    keep_tex: yes
tables: true
---

```{r, results='asis', echo=FALSE}

library(xtable)

my.df <- data.frame(matrix(c(1:18),nrow=2))

glossaryprint <- xtable(my.df, caption="Summary of Terms")

print(glossaryprint,
      comment=FALSE,
      floating=FALSE,
      size="footnotesize"
)

```

我能够通过在打印语句中不包括大小参数而是直接在块之前和之后包括大小参数来解决这个问题。

\begin{footnotesize}

#chunk

\end{footnotesize}

注意:问题的主题和此答案已在 xtable 1.8-2 中解决。


虽然该问题已通过解决方法自行回答,但我认为对于其他用户来说,更多详细信息可能会有所帮助。

会发生什么?

要了解此处发生的情况,我们需要仔细查看文档在从 RMD 到 PDF 的过程中所经历的转换步骤。步骤是:

RMD --> MD --> TEX --> PDF

让我们以相反的顺序查看文件:

  • PDF:(由 pdflatexTEX 生成)

  • TEX:(由 pandocMD 生成)

    % …
    \{\footnotesize
    
    \begin{tabular}{rrrr}
      \hline
     & X1 & X2 & X3 \ 
      \hline
    1 &   1 &   3 &   5 \ 
      2 &   2 &   4 &   6 \ 
       \hline
    \end{tabular}
    
    \}
     % …
    
  • MD(由 knitrRMD 生成)

    ---
    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 环境中。)

解决方案

了解了问题后,我们能做些什么呢?一种解决方案已经是 :避免在 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)生成的 LaTeX 代码在 pandoc 转换后仍然存在,那就太好了。这很简单:print.xtable 检查是否设置了 size,如果设置了,则在大小规范之前插入 { 并在 table 末尾插入 }

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,希望这个问题会在未来的版本中得到解决。