Libraries in script interfere with Rmd when calling render directly

Viewed 25

Suppose I have the following Rmd file called render-issues.Rmd:

---
title: "Render Issues"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

```{r lib}
library(dplyr)
```

```{r clash}
mtcars %>% summarize(n = n())
```

When pressing the knit button in R-Studio everything works as expected.

If I try to render this document "by hand" i.e. by calling rmarkdown::render in a script, I may fail:

library(dplyr)
library(rmarkdown)
library(Hmisc) ## note the conflict of summarize

render("render_issues.Rmd")

This won't render because summarize now refers to Hmisc::summarize.

Thus, I thought I could provide envir to make sure my Rmd file is not disturbed by the libs in my render script

### Use `parent` to simulate a fresh R session with the 
### standard libs loaded
render("render_issues.Rmd", 
       envir = new.env(parent = as.environment("package:stats")))

However, this won't work either, because now dplyr is not (re-) loaded and thus functions cannot be found. Apparently, library checks the whole search path irrespective of my environment choice.

So what is the canonical way of rendering a report from a script? Overall I want the render process to be completely un-disturbed by the calling script. Is the only solution to spawn a new R session as highlighted in this article?

1 Answers

Yes, the canonical way is to spawn a new R session.

You could alternatively play whack-a-mole and fix up the conflicts one at a time, by putting

summarize <- dplyr::summarize

and similar fixups in the individual Rmd files (or in the script), but I'd recommend running in a clean session. The method listed in the bookdown chapter isn't the only way, you can use base R functions to do it, e.g.

system("Rscript -e \"rmarkdown::render('render_issues.Rmd')\"")

(which I'd probably put in a function if you're calling it more than once).

Related