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

时间:2017-09-06 17:07:50

标签: r r-markdown kableextra

背景

我正在尝试制作使用render()呈现的rmarkdown文档。 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
```

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

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 - 对乳胶 - 来自   降价+ 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" !未定义的控制   序列。 \ begin {tabular} {rrrrl} \ toprule                                               Sepal.Length& Sepal.Width&宠物... l.267 \ end {tabular}}

     

pandoc.exe:生成PDF错误:pandoc文档转换   失败并出现错误43此外:警告消息:正在运行命令   '" C:/ Program Files / RStudio / bin / pandoc / pandoc" + RTS -K512m -RTS   test.utf8.md - 对乳胶 - 来自   降价+ 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必须在渲染之间关闭?

4 个答案:

答案 0 :(得分:18)

2019-01-21更新:

编织按钮和render功能之间的一个重要区别在于,编织按钮始终以“新环境”(我们都能感觉到)开始,而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}

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

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

答案 1 :(得分:5)

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

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

应该可以使用类似

的方式选择环境
rmarkdown::render('torender.Rmd',envir=new.env(some parameters))

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

答案 2 :(得分:1)

我有一个类似的问题:循环渲染包含表的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。

希望这对某人有帮助。

答案 3 :(得分: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}