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
new.env has a parent argument whose default is parent.frame()
— i.e. the caller. In other words, your new environment inherits all the stuff from your current environment.
You can avoid this by specifying parent
:
new.env(parent = baseenv())
Or, if you want to inherit loaded packages:
new.env(parent = as.environment(2))
And, yes, the render
documentation is somewhat misleading: while new.env()
provides a new, empty environment, it’s not entirely decoupled from the caller, and the caller probably almost never wants to use just new.env()
.
In order to be able to use packages inside a clean environment inherited from baseenv()
, you need to manually implement the package attachment mechanism because R packages do not support environment isolation by themselves (grrr!). Or you use the “modules” package, which supports locally attached packages:
```{r}
modules::import_package('ggplot2', attach = TRUE)
qplot(rnorm(10))
```
The attach = TRUE
argument causes the package to be attached locally, unlike library
.
Here’s a stripped-down version of the “modules” package loading code that could be used as well:
require_namespace = function (package) {
ns = .Internal(getRegisteredNamespace(package))
if (is.null(ns))
ns = tryCatch(loadNamespace(package), error = identity)
ns
}
exhibit_package_namespace = function (namespace, name, parent, export_list) {
structure(list2env(sapply(export_list, getExportedValue, ns = namespace,
simplify = FALSE),
parent = parent.env(parent)),
name = paste('package', name, sep = ':'),
path = getNamespaceInfo(namespace, 'path'))
}
library_local = function (package, parent = parent.frame()) {
pkg_ns = require_namespace(package)
if (inherits(pkg_ns, 'error'))
stop('Unable to load package ', sQuote(package), '\n',
'Failed with error: ', sQuote(conditionMessage(pkg_ns)))
export_list = getNamespaceExports(pkg_ns)
pkg_env = exhibit_package_namespace(pkg_ns, package, parent, export_list)
parent.env(parent) = pkg_env
}
Usage:
```{r}
library_local('ggplot2')
qplot(rnorm(10))
```