Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does rendering a pdf from rmarkdown require closing rstudio between renders?

Background

I am trying to make a rmarkdown document that is rendered using render(). The render call has two elements that are parameterized:

  • I would like the user to be able to specify pdf or html. Straightforward using output_format().
  • I also would like to pass a parameter to the document to specify if the tables (using the kableExtra package) are latex or html.

This is the rmarkdown file called test.Rmd

---
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
```

Now here are the two calls to render the file:

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

Problem

Now if I open up a fresh rstudio session I can run both render calls no problem. Either .pdf or an .html file is created. However if I then try to run the .pdf render again i get the following error:

"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" ! Undefined control sequence. \begin {tabular}{rrrrl} \toprule Sepal.Length & Sepal.Width & Pet... l.267 \end{tabular}}

pandoc.exe: Error producing PDF Error: pandoc document conversion failed with error 43 In addition: Warning message: running command '"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"' had status 43

The html render works fine over and over again. If I close rstudio, then ropen the project, the render for pdf work fine as well.

Question

  • Can anyone tell me why my pdf rendered rmarkdown document can't be rendered twice in a single session of rstudio?
  • Similarly, why does rstudio have to closed in between renderings?
like image 402
boshek Avatar asked Sep 06 '17 17:09

boshek


People also ask

How do I publish R Markdown as PDF?

To transform your markdown file into an HTML, PDF, or Word document, click the “Knit” icon that appears above your file in the scripts editor. A drop down menu will let you select the type of output that you want. When you click the button, rmarkdown will duplicate your text in the new file format.

What is the difference between Markdown and R Markdown?

R Markdown is an extension of the markdown syntax. R Markdown files are plain text files that typically have the file extension . Rmd . They are written using an extension of markdown syntax that enables R code to be embedded in them in a way which can later be executed.

What does knit document mean on RStudio?

Better still, RStudio includes a “Knit” button that enables you to render an . Rmd and preview it using a single click or keyboard shortcut.

What is render in R Markdown?

If you do not use RStudio or any other IDE, you need to know this fact: R Markdown documents are rendered through the function rmarkdown::render() . This means you can programmatically render an R Markdown document in any R script.


1 Answers

2019-01-21 UPDATE:

One of the big difference between the knit button and the render function is that, the knit button always starts with a "new environment" (as we all can feel) while the render function by default starts in the parent.env().

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

In the function documentation, we see

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

Therefore, we can simulate the behavior of clicking the knit button by putting envir = new.nev() in the render call.


Original Answer:

Hmm, let me post the solution first. To solve this behavior, you need to put the following stuff in your yaml section. I also added a function kableExtra_latex_packages() in the dev version earlier this week to bring up the following texts.

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}

If you are curious why there is such an odd behavior, here is a short explanation. When you first load kableExtra in a rmarkdown environement, it will try to put the LaTeX package information above into the rmarkdown metadata using the usepackage_latex() function that comes with this package. It works fine if you just hit the knit button because every "knit+rendering" process is supposed to be isolated. However, surprisingly (btw thanks for bringing it up), as we see it here, if you are trying to render from console, since (my assumption) knitr or rmarkdown is trying to reuse some cached results, this process failed to replicate. It turns out these LaTeX package dependencies were not put into the tex file being generated and ends up with an error. If you close RStudio and restart it, of course, the temporary memory it has will be gone and you should be able to load those packages again. I feel like it could be a global-variable-related bug in rmarkdown. I guess we can fix it by adding a "forget the meta" part at the end of the render function but I need to look it that.

Part of it was my bad for not providing enough documentations on LaTeX packages that were used in past releases. Now, I added a new section about this issue at the very beginning of the package vignette of kableExtra 0.5.0, which was released earlier this week. Feel free to check it out. Also, as I said earlier, in current dev version, you can bring up the list using the function kableExtra_latex_packages().

like image 77
Hao Avatar answered Oct 16 '22 15:10

Hao