17

背景

我正在尝试制作一个使用render(). 该render调用有两个参数化的元素:

  • 我希望用户能够指定 pdf 或 html。直接使用output_format().
  • 我还想将参数传递给文档以指定表(使用kableExtra包)是乳胶还是 html。

这是名为 test.Rmd 的 rmarkdown 文件

---
title: "Title"
author: "Zzz Zzzzzz"
params:
  table_format:
    value
---

```{r setup}
knitr::opts_chunk$set(echo = FALSE)
library(knitr)
library(kableExtra)

options(knitr.table.format = params$table_format) 
```

## Test table

```{r cars}
if (params$table_format == "latex"){
kable(iris[1:100,], booktabs = T) %>%
  kable_styling(latex_options = c("scale_down")) 
}

if (params$table_format == "html"){
kable(iris[1:100,]) %>%
  kable_styling(bootstrap_options = c("striped", "hover"))  %>%
  scroll_box(width = "500px", height = "600px")
}


params$table_format
```

现在这里是渲染文件的两个调用:

rmarkdown::render("test.Rmd", output_format = "pdf_document", params = list(
  table_format = "latex"
))


rmarkdown::render("test.Rmd", output_format = "html_document", params = list(
  table_format = "html"
))

问题

现在,如果我打开一个新的 rstudio 会话,我可以运行两个render调用都没有问题。创建 .pdf 或 .html 文件。但是,如果我再次尝试运行 .pdf 渲染,我会收到以下错误:

"C:/Program Files/RStudio/bin/pandoc/pandoc" +RTS -K512m -RTS test.utf8.md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output test.pdf --template " C:\Users\salbers\R\win-library\3.4\rmarkdown\rmd\latex\default-1.17.0.2.tex" --highlight-style tango --latex-engine pdflatex --variable graphics=yes --variable “几何:边距=1英寸”!未定义的控制序列。\begin {tabular}{rrrrl} \toprule Sepal.Length & Sepal.Width & Pet... l.267 \end{tabular}}

pandoc.exe:错误生成 PDF 错误:pandoc 文档转换失败,错误 43 另外:警告消息:运行命令“C:/Program Files/RStudio/bin/pandoc/pandoc”+RTS -K512m -RTS test.utf8。 md --to latex --from markdown+autolink_bare_uris+ascii_identifiers+tex_math_single_backslash --output test.pdf --template "C:\Users\salbers\R\win-library\3.4\rmarkdown\rmd\latex\default-1.17. 0.2.tex" --highlight-style tango --latex-engine pdflatex --variable graphics=yes --variable "geometry:margin=1in"' 状态为 43

html 渲染一次又一次地正常工作。如果我关闭 rstudio,然后关闭项目,pdf 的渲染也可以正常工作。

问题

  • 谁能告诉我为什么我的 pdf 渲染的 rmarkdown 文档不能在一次 rstudio 会话中渲染两次?
  • 同样,为什么 rstudio 必须在渲染之间关闭?
4

4 回答 4

26

2019-01-21 更新:

knit 按钮和render函数之间的最大区别之一是,knit 按钮总是以“新环境”开头(我们都可以感觉到),而render函数默认情况下以parent.env().

render(input, ..., envir = parent.frame(), ...)

在函数文档中,我们看到

envir   
The environment in which the code chunks are to be evaluated 
during knitting (can use new.env() to guarantee an empty new 
environment).

因此,我们可以通过渲染调用来模拟点击knit按钮的行为。envir = new.nev()


原答案:

嗯,让我先发布解决方案。要解决此问题,您需要将以下内容放入您的 yaml 部分。kableExtra_latex_packages()本周早些时候,我还在开发版中添加了一个功能来显示以下文本。

header-includes:
  - \usepackage{booktabs}
  - \usepackage{longtable}
  - \usepackage{array}
  - \usepackage{multirow}
  - \usepackage[table]{xcolor}
  - \usepackage{wrapfig}
  - \usepackage{float}
  - \usepackage{colortbl}
  - \usepackage{pdflscape}
  - \usepackage{tabu}
  - \usepackage{threeparttable}
  - \usepackage[normalem]{ulem}

如果你很好奇为什么会有这种奇怪的行为,这里有一个简短的解释。当你第一次kableExtra在 rmarkdown 环境中加载时,它会尝试使用usepackage_latex() 函数将上面的 LaTeX 包信息放入 rmarkdown 元数据中这个包附带的。如果您只是点击编织按钮,它就可以正常工作,因为每个“编织+渲染”过程都应该是孤立的。但是,令人惊讶的是(顺便说一句,感谢您提出它),正如我们在这里看到的那样,如果您尝试从控制台进行渲染,因为(我的假设)knitr 或 rmarkdown 正在尝试重用一些缓存的结果,因此该过程无法复制。事实证明,这些 LaTeX 包依赖项没有放入正在生成的 tex 文件中,最终出现错误。当然,如果你关闭 RStudio 并重新启动它,它所拥有的临时内存将会消失,你应该能够再次加载这些包。我觉得这可能是 rmarkdown 中与全局变量相关的错误。我想我们可以通过在函数末尾添加“忘记元”部分来修复它,render但我需要看看它。

部分原因是我没有提供足够的关于过去版本中使用的 LaTeX 包的文档。现在,我在本周早些时候发布的 kableExtra 0.5.0的开头添加了一个关于这个问题的新部分。随意检查一下。另外,正如我之前所说,在当前的开发版本中,您可以使用函数调出列表kableExtra_latex_packages()

于 2017-09-06T19:51:15.297 回答
7

在我的情况下,@Hao 的回答不起作用......我终于在每次渲染执行后卸载了 kableExtra 包,如下所示:

rmarkdown::render('torender.Rmd')
detach("package:kableExtra", unload=TRUE)

也应该可以使用类似的东西来选择环境

rmarkdown::render('torender.Rmd',envir=new.env(some parameters))

哪个更干净......但我没有这样管理!

于 2017-11-30T12:32:20.280 回答
4

我有一个类似的问题:一个循环来呈现包含表格的 PDF 报告。PDF 不会使用 booktabs = T 呈现。我的解决方案是手动加载从循环调用的 Rmd 脚本中我的设置​​块中的所有乳胶包。

因此,在多次调用的 Rmd 脚本中,我有:

usepackage_latex("booktabs")
usepackage_latex("longtable")
usepackage_latex("array")
usepackage_latex("multirow")
usepackage_latex("xcolor", "table")
usepackage_latex("wrapfig")
usepackage_latex("float")
usepackage_latex("colortbl")
usepackage_latex("pdflscape")
usepackage_latex("tabu")
usepackage_latex("threeparttable")
usepackage_latex("threeparttablex")
usepackage_latex("ulem", "normalem")
usepackage_latex("makecell")

这解决了问题 - 使用格式化表格呈现的 PDF。

希望这可以帮助某人。

于 2018-08-23T19:25:57.333 回答
0

我发现对多个 .Rmd 文件执行此操作的一种简单方法是使用这些 kableExtra 添加的 \usepackage{} 命令的列表创建一个“headers.tex”文件。然后在 .Rmd 文件的 YAML 头中:

output: 
  pdf_document:
    includes:
      in_header: headers.tex

这是我放入 header.tex 文件的内容——我从一个有效的文件中复制了它,它也是 kableExtra_latex_packages() 剥离“header-includes:”行和破折号的输出。

\usepackage{booktabs}
\usepackage{longtable}
\usepackage{array}
\usepackage{multirow}
\usepackage{wrapfig}
\usepackage{float}
\usepackage{colortbl}
\usepackage{pdflscape}
\usepackage{tabu}
\usepackage{threeparttable}
\usepackage{threeparttablex}
\usepackage[normalem]{ulem}
\usepackage{makecell}
\usepackage{xcolor}
于 2019-07-08T20:31:46.770 回答