代码之家  ›  专栏  ›  技术社区  ›  Andrew

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

  •  0
  • Andrew  · 技术社区  · 8 年前

    创建R Markdown网站时 rmarkdown::render_site() ,似乎每个编织文件都共享相同的环境,而knitr/R标记并不会为每个页面创建新的空环境。这会导致意外的命名空间问题,我不知道如何解决。

    例如,以以下5个文件为例:

    测试。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
    

    _现场。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
    

    指数Rmd

    ---
    title: "Testing"
    ---
    
    Hello, Website!
    

    01\u什么的。Rmd

    ---
    title: "Step 1"
    ---
    
    Write some data just for fun.
    
    ```{r}
    library(tidyverse)
    library(here)
    
    write_csv(mtcars, file.path(here(), "cars.csv"))
    ```
    

    02\u其他东西。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"))
    ```
    

    二者都 here lubridate 有一个 here() 函数,因为我想使用 润滑油 的整个脚本 02_something-else.Rmd ,我跑步 library(here) 之后 library(lubridate) 跑步 02\u其他东西。Rmd 以交互方式或自行编织的方式工作,只需按正确的顺序加载finepackage,一切都很好。

    但是,在使用 rmarkdown::render\u site() (从控制台、RStudio中的“Build”(构建)按钮,或从具有 Rscript -e "rmarkdown::render_site())" )R到达时出错 02\u其他东西。Rmd :

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

    而不是使用 here::here() ,R正在使用 lubridate::here() 并插入当前日期和时间,自 图书馆(此处) 最初加载于 01_something.Rmd 当R到达时,该环境似乎仍在加载 02\u其他东西。Rmd

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

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

    1 回复  |  直到 8 年前
        1
  •  1
  •   user2554330    8 年前

    这看起来像是 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)       
    }
    

    所以,只要在任何库调用之前调用这个函数,事情就会好起来。

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