强制R函数调用自给自足 [英] Force R function call to be self-sufficient

查看:140
本文介绍了强制R函数调用自给自足的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种调用不受.GlobalEnv中其他对象影响的函数的方法.

I'm looking for a way to call a function that is not influenced by other objects in .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(5) should fail, because y is not defined in the function scope
  • f2(iris) should pass, because the function does not reference variables outside its scope

现在,我可以将f1f2的环境覆盖为baseenv()new.env(parent=environment(2L)):

Now, I can overwrite the environment of f1 and f2, either to 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

或:

# 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

是否有一种方法可以覆盖函数环境,使其必须具有自给自足性,但是只要加载了自己的库,它就始终可以工作?

Is there a way to overwrite a function's environment so that it has to be self-sufficient, but it also always works as long as it loads its own libraries?

推荐答案

从根本上说,这里的问题是library和类似工具无法提供范围,并且不能与示波器一起使用: 1 即使library是在函数内部执行的,其作用实际上也是全局的,而不是局部的. gh.

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(通过attach)操纵search路径,并且该函数的环境没有被通知":它仍将指向 previous 第二个搜索路径条目,它的祖父母.

Specifically, your approach of isolating the function from the global environment is sounds; however, library manipulates the search path (via attach), and the function’s environment isn’t "notified" of this: it will still point to the previous second search path entry as its grandparent.

调用library/attach/…ist时,您需要找到一种更新功能环境的祖父母环境的方法.您可以通过使用自己的调用attach修改版的版本替换函数父环境中的library等来实现此目的.然后,此attach2不仅会调用原始的attach,还会重新链接环境的父级.

You need to find a way of updating the function environment’s grandparent environment when library/attach/… ist called. You could achieve this by replacing library etc. in the function’s parent environment with your own versions that calls a modified version of attach. This attach2 would then not only call the original attach but also relink your environment’s parent.

1 顺便说一句,模块› 修复了所有这些问题问题.在代码中用modules::import_package('foo', attach = TRUE)替换library(foo)使其起作用.这是因为模块具有很强的作用域并且具有环境意识.

1 As an aside, ‹modules› fixes all of these problems. Replacing library(foo) by modules::import_package('foo', attach = TRUE) in your code makes it work. This is because modules are strongly scoped and environment-aware.

这篇关于强制R函数调用自给自足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆