简体   繁体   中英

Use new environments for each knitted file in an R Markdown website?

When building an R Markdown website with rmarkdown::render_site() , it seems that each of the knitted files all share the same environment and knitr/R Markdown does not create a new empty environment for each individual page. This causes unexpected namespace issues that I can't figure out how to get rid of.

For example, take this minimum working example with the following 5 files:

testing.Rproj

Version: 1.0

RestoreWorkspace: Default
SaveWorkspace: Default
AlwaysSaveHistory: Default

EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 2
Encoding: UTF-8

RnwWeave: Sweave
LaTeX: pdfLaTeX

AutoAppendNewline: Yes

BuildType: Website

_site.yml

name: "testing"
navbar:
  title: "Testing"
  left:
    - text: "Home"
      href: index.html
    - text: "Step 1"
      href: 01_something.html
    - text: "Step 2"
      href: 02_something-else.html

index.Rmd

---
title: "Testing"
---

Hello, Website!

01_something.Rmd

---
title: "Step 1"
---

Write some data just for fun.

```{r}
library(tidyverse)
library(here)

write_csv(mtcars, file.path(here(), "cars.csv"))
```

02_something-else.Rmd

---
title: "Step 2"
---

This breaks because `lubridate::here()` and `here::here()` conflict, but *only* when rendering the whole site.

```{r}
library(tidyverse)
library(lubridate)
library(here)

# Do something with lubridate
my_date <- ymd("2018-04-19")

# Try to use here() and it breaks when rendering the whole site
# It works just fine when knitting this file on its own, though, since here is loaded after lubridate
cars <- read_csv(file.path(here(), "cars.csv"))
```

Both here and lubridate have a here() function, and because I want to use lubridate 's throughout the script in 02_something-else.Rmd , I run library(here) after library(lubridate) . Running 02_something-else.Rmd interactively or knitting it by itself works just fine—package loading happens in the right order and everything's great.

However, when building the site with rmarkdown::render_site() (from the console, from the "Build" button in RStudio, or from the terminal with Rscript -e "rmarkdown::render_site())" ) there's an error when R gets to 02_something-else.Rmd :

Error: '2018-04-19 14:53:59/cars.csv' does not exist in current working directory

Instead of using here::here() , R is using lubridate::here() and inserting the current date and time, since library(here) was originally loaded in 01_something.Rmd and that environment seems to still be loaded when R gets to 02_something-else.Rmd .

According to the documentation for rmarkdown::render_site() , you can use the envir = new.env() argument to ensure that the site rendering uses a new environment, but that doesn't fix the problem. It seems that guarantees a new environment for the overall site building process, but not for the individual files.

Is there a way to ensure that each individual file in an R Markdown website gets its own new environment when knitted?

This looks like a flaw in the design of rmarkdown::render_site , but it's easy to work around. The problem isn't that the here package is loaded, the problem is that it's on the search list. So you should remove it. (Removing things from the search list is easier than unloading them, and is generally pretty safe.)

It seems like a good defensive measure would be to clean up your search list at the start of each document. This function does that:

cleanSearch <- function() {
    defaults <- c(".GlobalEnv", 
                  paste0("package:", getOption("defaultPackages")),
                  "Autoloads",
                  "package:base")
    currentList <- search()  
    deletes <- setdiff(currentList, defaults)
    for (entry in deletes)
      detach(entry, character.only = TRUE)       
}

So just call this function before any library calls, and things should be fine.

Edited to add: oops, I see in the comments you found similar solutions already. Well, my function looks cleaner than those, and safer....

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM