I've found that a knitr document inherits variables from the user's environment, even if the argument envir = new.env()
is provided. How can I prevent it from inheriting these variables?
For instance, suppose I wrote a simple .Rmd file using a variable that doesn't exist (y
), knitted it, and showed the resulting file:
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
# ```
Of course, I get an error that the y
variable doesn't exist, just as I should.
However, if I then define y
in my own environment, I find I can now refer to y
in the .Rmd file, even though I give the envir = new.env()
argument.
y <- 3
knit("test.Rmd", quiet = TRUE, envir = new.env())
# [1] "test.md"
cat(readLines("test.md"), sep = "\n")
#
# ```r
# y + 1
# # [1] 4
# ```
My understanding was that envir = new.env()
should have caused the knitr document to be evaluated in a new environment without the y
variable. This is a problem because it allows knitr documents to be non-reproducible, referring to variables I don't define within the document.
Note that the rmarkdown render
documentation (which is a wrapper around knit
) specifically says you can use envir = new.env()
:
The environment in which the code chunks are to be evaluated during knitting (can use new.env() to guarantee an empty new environment).
However, render
shows the same behavior as above, for the same reason. Are my expectations (and the rmarkdown docs) incorrect about envir = new.env()
, or am I using it incorrectly? And is there another way to guarantee a new environment in a document being knitted?