简体   繁体   English

在调用环境中评估 function

[英]evaluate a function in the calling environment

I have the function below.我有下面的 function。

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

Is there a way I run this function and a and b will be assigned in the parent environment (in this case globalenv)?有没有办法运行这个 function 并且 a 和 b 将在父环境中分配(在本例中为 globalenv)? I don't want to modify the function (no assign with envir or <<- ), but call it in a way that what I want will be achieved.我不想修改 function (不使用 envir 或<<- assign ),但以我想要的方式调用它。

A better pattern to use, from the point of encapsulation, might be to have your custom function return a 2D vector containing the a and b values:从封装的角度来看,使用更好的模式可能是让您的自定义 function 返回包含ab值的二维向量:

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

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

The preferred method for passing information/work done in a function is via the return value, rather than trying to manage the issue of different scopes.传递在 function 中完成的信息/工作的首选方法是通过返回值,而不是尝试管理不同范围的问题。

Normally R functions return their outputs.通常 R 函数会返回它们的输出。 Functions such as test_fun are discouraged but if you want to do it anyways use trace as shown below.不鼓励使用诸如test_fun类的函数,但如果您想这样做,请使用如下所示的trace This will cause the code given in the exit argument to run at function exit.这将导致 exit 参数中给出的代码在 function 出口处运行。 No packages are used.不使用任何包。

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

Alternatives备择方案

Some alternatives for the exit= argument are the following. exit= 参数的一些替代方法如下。

(a) below is similar to above except that rather than leaving the objects loose in the global environment it first creates an environment env in the global environment and puts them there. (a) 下面与上面类似,只是它不是让对象在全局环境中松散,而是首先在全局环境中创建一个环境env并将它们放在那里。

In (b) below, the objects are copied to environment(test_fun) which is the environment in which test_fun is defined .在下面的 (b) 中,对象被复制到environment(test_fun)中,这是定义test_fun的环境。 (If test_fun is defined in the global environment then it gives the same result as the code at the top of the answer.) (如果test_fun在全局环境中定义,那么它给出的结果与答案顶部的代码相同。)

In (c) below, the parent frame of test_fun is the environment of the caller of test_fun and can vary from one call to another if called from different places.在下面的 (c) 中,test_fun 的父框架是test_fun调用者的环境,如果从不同的地方调用, test_fun可能会因调用而异。 (If called from the global environment then it gives the same result as the code at the top of the answer.) (如果从全局环境调用,那么它给出的结果与答案顶部的代码相同。)

It would also be possible to add the current frame within test_fun to the search path using attach but there are a number of gotchas associated with that so it is not shown.也可以使用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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM