【发布时间】:2015-11-22 08:14:15
【问题描述】:
我发现 knitr 文档从用户环境继承变量,即使提供了参数 envir = new.env()。如何防止它继承这些变量?
例如,假设我使用不存在的变量 (y) 编写了一个简单的 .Rmd 文件,将其编织,并显示生成的文件:
library(knitr)
writeLines(c("```{r}", "y + 1", "```"), "test.Rmd")
knit("test.Rmd", quiet = TRUE, envir = new.env())
# [1] "test.md"
cat(readLines("test.md"), sep = "\n")
#
# ```r
# y + 1
# #> Error in eval(expr, envir, enclos): object 'y' not found
# ```
当然,我得到了一个错误,即 y 变量不存在,正如我应该的那样。
但是,如果我随后在自己的环境中定义 y,我发现我现在可以在 .Rmd 文件中引用 y,即使我给出了 envir = new.env() 参数。
y <- 3
knit("test.Rmd", quiet = TRUE, envir = new.env())
# [1] "test.md"
cat(readLines("test.md"), sep = "\n")
#
# ```r
# y + 1
# # [1] 4
# ```
我的理解是 envir = new.env() 应该导致在没有 y 变量的新环境中评估 knitr 文档。这是一个问题,因为它允许 knitr 文档不可重现,指的是我未在文档中定义的变量。
请注意,rmarkdown render documentation(它是knit 的包装)明确表示您可以使用envir = new.env():
在编织过程中要评估代码块的环境(可以使用 new.env() 来保证一个空的新环境)。
但是,render 显示与上述相同的行为,原因相同。我对envir = new.env() 的期望(和 rmarkdown 文档)是不正确的,还是我使用不正确?还有其他方法可以保证正在编织的文档中的新环境吗?
【问题讨论】:
-
你可以使用 baseenv 代替
-
@rawr 如果我使用
baseenv,我将无法在 knitr 块中加载任何包。例如,尝试将以上行更改为writeLines(c("```{r}", "library(ggplot2)", "qplot(rnorm(100))"), "test.Rmd"); knit("test.Rmd", quiet = TRUE, envir = baseenv())