如何在当前环境中“实例化”环境?

时间:2016-09-27 17:39:22

标签: r

假设函数foo返回其环境,如下所示:

foo <- function () {
  a <- 42
  b <- "a string"
  x <- FALSE
  environment()
}

...而且该函数bar像这样调用foo

bar <- function () {
  a <- 0
  z <- pi

  cat("before\n")
  print(ls.str())

  INSTANTIATE(foo())

  cat("after\n")
  print(ls.str())
}

...其中INSTANTIATE占位符,用于尚未定义的函数(或构造)。

假设表达式INSTANTIATE(foo())旨在作为指令

的简写
  

在当前环境中实例化foo()返回的环境。

通过“实例化”,我的意思是foo()中提到的所有变量都在当前环境中创建(如有必要),并分配给foo()中的值。

这意味着bar()的所需输出如下:

> bar()
before
a :  num 0
z :  num 3.14
after
a :  num 42
b :  chr "a string"
x :  logi FALSE
z :  num 3.14

我的问题是,我该如何替换INSTANTIATE(foo())这样的表达式,使bar()的输出看起来像我上面所示?

编辑:请假设foo应保持不变。

编辑:这个INSTANTIATE(foo())的实现,受格雷戈尔的评论(或者说,我的解释)的启发,不起作用:

bar <- function () {
  a <- 0
  z <- pi
  cat("before\n")
  print(ls.str())

  list2env(as.list(foo()))

  cat("after\n")
  print(ls.str())
}

> bar()
before
a :  num 0
z :  num 3.14
after
a :  num 0
z :  num 3.14

1 个答案:

答案 0 :(得分:2)

这样的事情

import_env <- function(env, to=parent.frame()) {
    vars <- ls(envir=env)
    for(v in vars) {
        assign(v, get(v, env),to)
    }
}

使用

进行测试
foo <- function () {
  a <- 42
  b <- "a string"
  x <- FALSE
  environment()
}

bar <- function () {
  a <- 0
  z <- pi

  cat("before\n")
  print(ls.str())

  import_env(foo())

  cat("after\n")
  print(ls.str())
}

bar()
# before
# a :  num 0
# z :  num 3.14
# after
# a :  num 42
# b :  chr "a string"
# x :  logi FALSE
# z :  num 3.14

基本上我们只是迭代环境并分配所有变量。这适用于原子类型。如果您曾尝试复制保留创建它们的环境的函数或公式,事情会变得有点棘手。