我正在寻找一种方法来调用不受其他对象影响的函数.GlobalEnv
.
看一下下面两个函数:
y = 3
f1 = function(x) x+y
f2 = function(x) {
library(dplyr)
x %>%
mutate(area = Sepal.Length *Sepal.Width) %>%
head()
}
在这种情况下:
-
f1(5)
应该失败,因为y
未在函数作用域中定义
-
f2(iris)
应该通过,因为该函数不会引用其范围之外的变量
现在,我可以覆盖环境f1
and f2
,要么baseenv()
or new.env(parent=environment(2L))
:
environment(f1) = baseenv()
environment(f2) = baseenv()
f1(3) # fails, as it should
f2(iris) # fails, because %>% is not in function env
or:
# detaching here makes `dplyr` inaccessible for `f2`
# not detaching leaves `head` inaccessible for `f2`
detach("package:dplyr", unload=TRUE)
environment(f1) = new.env(parent=as.environment(2L))
environment(f2) = new.env(parent=as.environment(2L))
f1(3) # fails, as it should
f2(iris) # fails, because %>% is not in function env
有没有办法覆盖函数的环境,使其必须自给自足,但只要加载自己的库,它就始终可以工作?
The problem here is, fundamentally, that library
and similar tools don’t provide scoping, and are not designed to be made to work with scopes:1 Even though library
is executed inside the function, its effect is actually global, not local. Ugh.
具体来说,您将函数与全局环境隔离的方法是声音;然而,library
操纵search
路径(通过attach
),并且函数的环境不会被“通知”这一点:它仍然会指向previous第二个搜索路径条目作为其祖父母。
你需要找到一种方法updating函数环境的祖父母环境library
/attach
/…被调用。您可以通过替换来实现此目的library
等等,在函数的父环境中使用您自己的版本调用修改版本attach
. This attach2
那么不仅会调用原来的attach
还要重新链接您的环境的父级。
1 As an aside, ‘box https://klmr.me/box/’ fixes all of these problems. Replacing library(foo)
with box::use(foo[...])
in your code makes it work. This is because modules are strongly scoped and environment-aware.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)