为什么从rmarkdown渲染pdf需要在渲染之间关闭rstudio?

bos*_*hek 14 r r-markdown kableextra

背景

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

  • 我希望用户能够指定pdf或html.直截了当使用output_format().
  • 我还想将一个参数传递给文档,以指定表(使用kableExtra包)是否为latex或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
```
Run Code Online (Sandbox Code Playgroud)

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

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

问题

现在,如果我打开一个新的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 "几何:margin = 1in"!未定义的控制序列.\ 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" - 高亮式探戈--latex-engine pdflatex - 变量图形=是 - 变量"几何:margin = 1in"'状态43

html渲染一次又一次正常工作.如果我关闭rstudio,然后浏览项目,pdf的渲染工作也很好.

  • 谁能告诉我为什么我的pdf呈现的rmarkdown文档无法在rstudio的单个会话中呈现两次?
  • 同样,为什么rstudio必须在渲染之间关闭?

Hao*_*Hao 23

2019-01-21更新:

编织按钮和render功能之间的最大区别之一是,编织按钮始终以"新环境"开始(我们都能感觉到),而render默认情况下,该功能始于parent.env().

render(input, ..., envir = parent.frame(), ...)
Run Code Online (Sandbox Code Playgroud)

在功能文档中,我们看到了

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

因此,我们可以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}
Run Code Online (Sandbox Code Playgroud)

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

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


小智 6

在我的情况下,@ Hau的答案不起作用...我最终在每次渲染执行后管理卸载kableExtra包,如下所示:

rmarkdown::render('torender.Rmd')
detach("package:kableExtra", unload=TRUE)
Run Code Online (Sandbox Code Playgroud)

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

rmarkdown::render('torender.Rmd',envir=new.env(some parameters))
Run Code Online (Sandbox Code Playgroud)

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