在调用环境中评估函数

时间:2020-07-26 03:21:47

标签: r

我具有以下功能。

test_fun <- function() {
  a <- 1
  b <- 2
}

有没有一种方法可以运行此函数,并且将在父环境(在本例中为globalenv)中分配a和b?我不想修改该功能(使用envir或assign都不能修改<<-,但可以通过实现我想要的方式来调用它。

2 个答案:

答案 0 :(得分:2)

通常,R函数返回其输出。 test_fun 之类的函数 不鼓励这样做,但是如果您仍要这样做,请使用trace,如下所示。这将使exit参数中给出的代码在函数exit处运行。不使用任何软件包。

trace("test_fun", exit = quote(list2env(mget(ls()), globalenv())), print = FALSE)
test_fun()
a;b
## [1] 1
## [1] 2

替代品

exit =参数的一些替代方法如下。

(a)与上面的类似,不同之处在于它不是在全局环境中放置对象,而是先在全局环境中创建一个环境env并将其放置在那里。

在下面的(b)中,将对象复制到environment(test_fun)的环境中,其中test_fun定义的。 (如果在全局环境中定义了test_fun,则其结果与答案顶部的代码相同。)

在下面的(c)中,test_fun的父帧是test_fun的调用方的环境,如果从不同的位置调用,则在一个调用之间可能会有所不同。 (如果从全局环境中调用,则其结果将与答案顶部的代码相同。)

也可以使用attach将test_fun中的当前帧添加到搜索路径中,但是存在许多与此相关的陷阱,因此未显示。

# (a) copy objects to environment env located in global environment
assign("env", new.env(), globalenv())
trace("test_fun", exit = quote(list2env(mget(ls()), env)), print = FALSE)

# (b) copy objects to environment in which test_fun is defined
trace("test_fun", 
  exit = quote(list2env(mget(ls()), environment(test_fun)), print = FALSE)

# (c) copy object to parent.frame of test_fun; 5 needed as trace adds layers
trace("test_fun", exit = quote(list2env(mget(ls()), parent.frame(5))),
  print = FALSE)

答案 1 :(得分:1)

从封装的角度来看,更好的模式是让您的自定义函数返回包含ab值的2D向量:

test_fun <- function() {
    a <- 1
    b <- 2
    return(c(a, b))
}

result <- test_fun()
a <- result[1]
b <- result[2]

传递函数中完成的信息/工作的首选方法是通过返回值,而不是尝试管理不同范围的问题。