【问题标题】:RStudio 1.1.383 and rmarkdown 1.7 environment enheritanceRStudio 1.1.383 和 rmarkdown 1.7 环境继承
【发布时间】:2017-11-14 11:18:42
【问题描述】:

在 Windows 7 64 位上,我最近更新到 RStudio 1.1.383 和 rmarkdown 1.7。当我使用 render 从 Rmd 文件生成 pdf 时,我注意到了一种新行为。

  1. 全球环境和针织环境之间存在泄漏,这是双向的:
  2. 如果我在.Rmd文件中定义x = 12,渲染完成后我会在全局环境中找到x
  3. 如果我在 .Rmd 中使用未定义变量 y 并在使用 render 之前在全局环境中设置 y=1000y 用于 .Rmd 的编织
  4. 如果我从 RStudio 编织,则不会发生泄漏,即使在全局环境中定义了 y,编织 .Rmd 也会出错(未找到)。

有谁知道这是为什么?我相信分离环境对于确保可重复性非常重要,即使有时做对会很痛苦。

这是我的sessionInfo()

> sessionInfo()
R version 3.4.2 (2017-09-28)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252  LC_CTYPE=English_United States.1252    LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                           LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] rmarkdown_1.7

loaded via a namespace (and not attached):
 [1] compiler_3.4.2  backports_1.1.1 magrittr_1.5    rprojroot_1.2   htmltools_0.3.6 tools_3.4.2     yaml_2.1.14     Rcpp_0.12.13   
 [9] stringi_1.1.5   knitr_1.17      stringr_1.2.0   digest_0.6.12   evaluate_0.10.1

这是最小的“test render.R”文件:

library(rmarkdown)
y=1000
render(input = "test render.Rmd")

这是最小的“test render.Rmd”文件:

---
title: "test render"
author: "Courvoisier"
output: pdf_document
---

## R Markdown

```{r cars}
x = 12
print(y)
```

这是 pdf 结果:

【问题讨论】:

  • 这对community.rstudio.com来说可能是一个更好的问题。
  • 没错,但他们建议先把它放在这里
  • 如果有帮助的话,我相信rmarkdown 1.7 昨天发布了,并且相对于 1.6 和 1.5 有很多变化。
  • 啊,谢谢。我以为是八月份(github上的发布版)。我猜它昨天才在 CRAN 上播出。
  • @lmo StackOverflow 完全没问题,我个人强烈推荐 StackOverflow 进行问答。作为 rmarkdown 包的维护者,我很少阅读 community.rstudio.com 上的帖子(我只是没有时间),但我阅读了 StackOverflow 上的每一篇帖子。我们不建议用户在两个站点之间来回移动,除非 SO 上的问题显然不适合作为问题。

标签: r rstudio knitr r-markdown


【解决方案1】:

据我所知,这种行为从第一天起就一直存在。下面是证明它的方法。首先安装 rmarkdown from the CRAN archive:

的第一个版本 (0.3.3)
devtools::install_version('rmarkdown', '0.3.3')

然后运行你的例子:

library(rmarkdown)
y = 1000
render(input = "test render.Rmd")

您会看到 y 已打印(如我所料):

这种行为是设计使然,我不知道您为什么会感到惊讶。在 R 中,全局变量可以从任何地方访问(根据定义)。您在全局环境中定义了y,并且您应该期望它也可以在 R Markdown 文档中访问。

R Markdown 文档是在render() 的环境parent.frame() 中编译的,所有变量都会在这个环境中创建。在您的情况下,parent.frame() 是全局环境(即globalenv()),这就解释了为什么在全局环境中创建了x

当您单击 RStudio 中的 Knit 按钮时,情况有所不同,因为文档是在单独的新(干净)R 会话中编译的。您在当前 R 会话中定义的变量 y 将不可用于新的 R 会话。同样,x 将在新会话中创建,而不是在您当前的 R 会话中。可重复性正是我们选择在新的 R 会话而不是当前的 R 会话中编译 R Markdown 文档的原因。如果文档在新的 R 会话中工作,它更有可能是可重现的。如果它在您当前的 R 会话中有效(通过rmarkdown::render()),它可能只是偶然有效。

如果您必须在单独的环境中评估代码块,则需要显式使用参数envir,例如

render(input = "test.Rmd", envir = new.env())

这样,x 将不会在您的全局环境中创建,但 y 将可用于代码块(同样,通过全局变量的定义)。

总而言之,如果您真的关心可重复性(就像我们一样),有一种简单的方法,也有一种稍微困难的方法。简单的方法是单击 RStudio 中的 Knit 按钮,更难的方法是自己在单独的 R 会话中渲染文档,例如通过命令行

Rscript -e "rmarkdown::render('test.Rmd')"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 1970-01-01
    • 2023-01-19
    • 2018-04-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    相关资源
    最近更新 更多