如何将`````传递给R中的新环境?

时间:2016-08-10 18:37:57

标签: r

我的最终目标是能够拥有以下功能:

  • 对函数进行操作并返回函数
  • return函数创建一个新环境,其中.GlobalEnv作为其父级,
  • 评估新环境中的参数函数。

它的工作原理如下:

# Create an object that doesn't exist in the new.env
iris2 <- iris
model <- in_new_env(lm)(Sepal.Length ~ Sepal.Width, iris2)

我想要这样做的原因是我经常有应用程序,我想在一个函数内生成一个模型/ ggplot,该函数包含不直接在model / ggplot调用中使用的大项。因为这些对象随身携带它们的调用环境,所以对象在保存时会变得非常大,或者从并行集群中移回。

我的开始尝试是:

in_new_env <- function(.f){
  function(...) {
    env <- new.env(parent = globalenv())
    # This doesn't seem to actually export the ... to env
    assign("...", ..., envir = env)
    env$.f <- .f
    with(env, .f(...))
    # Error in eval(expr, envir, enclos) : '...' used in an incorrect context
  }
}

如果我能够将...导出到env,这将有效。我该怎么做呢?可能吗?您对in_new_env的替代策略有什么建议吗?

这将成为Bill Dunlap here建议的解决方案的便捷包装。

1 个答案:

答案 0 :(得分:4)

...本身并不是一个变量,所以你无法真正分配它。如果我认为我理解你要做什么,你可以使用类似list(...)的东西来评估传递给函数的所有参数并将它们存储在列表中。然后,您可以使用do.call()将该参数列表传递给另一个函数,并在evalq的其他环境中对其进行评估。我认为这可以做你想要的......

in_new_env <- function(.f){
  function(...) {
    params <- list(...)
    env <- new.env(parent = globalenv())
    assign(".params.", params, envir = env)
    env$.f <- .f
    evalq(do.call(".f", .params.), envir=env)

  }
}

iris2 <- iris
model <- in_new_env(lm)(Sepal.Length ~ Sepal.Width, iris2)

当然对对象的调用有点过时,因为它会记住.f函数名称,但我不清楚你的计划是针对你提出的函数。