在R Markdown网站中为每个针织文件使用新环境?

时间:2018-04-19 21:16:52

标签: r r-markdown knitr

在使用rmarkdown::render_site()构建R Markdown网站时,似乎每个针织文件都共享相同的环境,而knitr / R Markdown不会为每个单独的页面创建新的空白环境。这会导致意外的命名空间问题,我无法弄清楚如何摆脱。

例如,将此最小工作示例与以下5个文件一起使用:

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

herelubridate都有here()个功能,因为我想在lubridate的整个脚本中使用02_something-else.Rmd,我在library(here)后运行library(lubridate)。以交互方式运行02_something-else.Rmd或自行编织工作只需按正确的顺序进行精细包装加载,一切都很棒。

但是,使用rmarkdown::render_site()构建网站时(来自控制台,来自RStudio中的&#34; Build&#34;按钮,或来自Rscript -e "rmarkdown::render_site())"的终端)当R到达02_something-else.Rmd时出错:

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

而不是使用here::here(),R使用lubridate::here()并插入当前日期和时间,因为library(here)最初是在01_something.Rmd中加载的,并且该环境似乎仍然是当R到达02_something-else.Rmd时加载。

根据the documentation for rmarkdown::render_site(),您可以使用envir = new.env()参数来确保网站渲染使用新环境,但这并不能解决问题。它似乎保证了整个站点构建过程的新环境,但不是单个文件。

有没有办法确保R Markdown网站中每个单独的文件在针织时获得自己的新环境?

1 个答案:

答案 0 :(得分:1)

这似乎是rmarkdown::render_site设计中的一个缺陷,但它很容易解决。问题不在于加载here包,问题在于它在搜索列表中。所以你应该删除它。 (从搜索列表中删除内容比卸载它们更容易,并且通常非常安全。)

似乎一个好的防御措施是在每个文档的开头清理搜索列表。这个功能可以做到:

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

所以只需在任何库调用之前调用此函数,事情应该没问题。

编辑添加:oops,我在评论中看到你已经找到了类似的解决方案。好吧,我的功能看起来比那些更干净,更安全......