从另一个环境调用函数

时间:2016-02-10 20:54:45

标签: r

我今天似乎遇到了功能环境问题。我有一堆对象,其中许多是相互调用的函数,作为.RData文件保存到我的驱动器中:

irrelevant_var <- 123
fun1 <- function(x) x+fun2(x)
fun2 <- function(x) x^2
save(irrelevant_var, fun1, fun2, file = "myEnv.RData")
rm(irrelevant_var, fun1, fun2)

然后我将这些对象加载到新环境中:

myEnv <- new.env()
load("myEnv.RData", envir = myEnv)

然后我创建了一个新的元函数来处理myEnv中的对象。

meta_fun <- function(x) fun1(x)
meta_fun(1)
Error in meta_fun(1) : could not find function "fun1"

现在调用meta_fun将无效,因为fun1位于其他环境中,所以我这样做:

environment(meta_fun) <- myEnv

现在,我希望打电话给meta_fun,然后找到fun1,但现在找不到fun2

meta_fun(1)
Error in fun1(x) : could not find function "fun2"

如何让meta_fun工作?此外,事先不知道myEnv中有多少函数或它们是如何嵌套的。

1 个答案:

答案 0 :(得分:0)

首先,我强烈建议您重新考虑您的策略。试图在特定环境中运行代码(未附加到搜索路径)真的不那么有趣。

现在,问题出在fun1fun2的环境中。您可以在此示例中在全局环境中定义它们,以便反映在函数的environment()属性中(函数捕获定义它们的环境)。这意味着尽管名称fun1存在于myEnv环境中,但该函数的环境指向全局,而不是myEnv(它不会因为重新加载而改变,没有重新定义)。因此,它无法解析fun2符号。参见:

environment(myEnv$fun1)
# <environment: R_GlobalEnv>

如果你想在环境中构建这些功能,那么更好的方法是

myEnv <- new.env()
evalq({
    fun1 <- function(x) x+fun2(x)
    fun2 <- function(x) x^2
}, myEnv)

现在查看环境

environment(myEnv$fun1)
# <environment: 0x7ff507b31860>
myEnv
# <environment: 0x7ff507b31860>

然后你可以1)在同一个环境中定义你的meta_fun

evalq(meta_fun <- function(x) fun1(x), myEnv)
meta_fun(4)
# [1] 20

或2)改变meta_fun的环境,就像之前那样

meta_fun <- function(x) fun1(x)
environment(meta_fun) <- myEnv
meta_fun(4)
# [1] 20

此外,我非常确定attach()除非您尝试写入对象,否则不会复制对象。如果您对此有不同的参考,我有兴趣看到它。