在指定尺寸后使用xtable和knitr时的额外花括号

Raf*_*uez 1 latex r xtable knitr r-markdown

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

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

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"
)

```
Run Code Online (Sandbox Code Playgroud)

CL.*_*CL. 5

注意: 问题和答案的主题问题已在xtable1.8-2中得到解决.


虽然这个问题已通过解决方法自行解决,但我认为对其他用户而言,更多细节可能会有所帮助.

怎么了?

要了解这里发生的事情,我们需要仔细研究文档在从RMD到PDF的过程中经历的转换步骤.步骤是:

RMD --> MD --> TEX --> PDF
Run Code Online (Sandbox Code Playgroud)

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

  • PDF:( TEX由... 生成pdflatex)

PDF输出

  • TEX:( MD由... 生成pandoc)

    % …
    \{\footnotesize
    
    \begin{tabular}{rrrr}
      \hline
     & X1 & X2 & X3 \\ 
      \hline
    1 &   1 &   3 &   5 \\ 
      2 &   2 &   4 &   6 \\ 
       \hline
    \end{tabular}
    
    \}
     % …
    
    Run Code Online (Sandbox Code Playgroud)
  • MD(RMD由... 生成knitr)

    ---
    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}
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 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"
    )
    ```
    
    Run Code Online (Sandbox Code Playgroud)

回想一下:问题是,中有明显的花括号PDF.他们来自哪里?

  • 它们是TEX文件(\{\})中转义的花括号的结果.
  • 这些花括号也存在于MD文件中,但它们不会被转义.

所以我们现在知道两件事:我们看到花括号因为它们被转义而且它们被转义pandoc.

但为什么这些花括号存在呢?指定print.xtablea时输出它们size.目标是创建一个组并size仅在该组中应用.(有了floating = TRUE,不需要花括号分组,因为有一个figure环境size可以设置.无论如何都会打印花括号.)

为什么pandoc逃脱那对花括号,但留下所有其他花括号(例如\begin{tabular})未转义?这是因为pandoc它应该逃避特殊字符,这些字符意味着字面意义,但保留原始的LaTeX未转义.但是,pandoc 不知道外部花括号是LaTeX命令而不是文本.

(floating = TRUE由于花括号位于figure被识别为LaTeX 的环境中,因此不会出现此问题.)

解决方案

在了解了问题之后,我们能做些什么呢?OP已经发布了一个解决方案:禁止进入size,print.xtablefootnotesize手动插入命令:

    ---
    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}")
    ```
Run Code Online (Sandbox Code Playgroud)

但是,从长远来看,如果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"
}
Run Code Online (Sandbox Code Playgroud)

这个小的修改替换{\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"
}
Run Code Online (Sandbox Code Playgroud)

对于LaTeX来说,这没有什么区别,但是正如pandoc认识到的那样\begingroup(它被反对{)它应该解决问题.我报这是一个错误xtable,并希望该问题将在未来的版本.