【问题标题】:efficiently move environment from inside function to global environment有效地将环境从内部功能移动到全局环境
【发布时间】:2014-02-06 06:54:13
【问题描述】:

我有一个在其中创建环境的函数,我希望将该环境分配给全局环境。目前我通过将环境分配给globalenv() 作为最后一步来做到这一点——如下:

funfun <- function(inc = 1){
    dataEnv <- new.env()
    dataEnv$d1 <- 1 + inc
    dataEnv$d2 <- 2 + inc
    dataEnv$d3 <- 2 + inc
    assign('dataEnv', dataEnv, envir = globalenv())
}

感觉当函数funfun 结束时我应该能够做一些事情来使dataEnv 持续存在(以保存最后复制环境)但是我的尝试,例如dataEnv &lt;- new.env(parent = globalenv()),没有奏效。

为什么会失败?这可能吗?

另外,最有效的方法是什么?

我的表有时非常大,随着项目的发展,复制将成为一个问题。

【问题讨论】:

    标签: r environment


    【解决方案1】:

    退出函数时,您的环境不会被破坏。你只需要返回一个对它的引用。

    funfun <- function(inc = 1){
      dataEnv <- new.env(parent=globalenv())
      dataEnv$d1 <- 1 + inc
      dataEnv$d2 <- 2 + inc
      dataEnv$d3 <- rnorm(10000)
      return(dataEnv)
    }
    
    
    myEnv <- funfun()
    object.size(myEnv)
    

    拿出一些东西

    head(myEnv$d3)
    

    【讨论】:

    • 需要退货吗?或者仅仅将 dataEnv 作为函数的最后一行就足够了吗?我永远不确定 r 中的 return 语句。
    • return 不是必须的,你可以把值放在最后。如果你对我最近读到的风格有疑问google-styleguide.googlecode.com/svn/trunk/Rguide.xml。我认为他们在某些示例中确实使用了return。但这只是口味问题。
    • 这似乎提出了一个“垃圾收集”的问题。假设您不返回环境参考?你如何检测到dataEnv 的存在,如果没有别的,你可以在不需要的时候删除它?
    • 我不是专家,但如果您不返回任何引用,则在调用 gc() 时仍然会进行垃圾收集,因为已经可访问的对象中不存在引用。当垃圾收集器启动时,将运行标记和清除算法,从可达对象(例如 baseEnv)中,将递归找到所有具有引用的对象并将其标记为可达。由于我们没有返回引用,在这种情况下,对全局 env 的引用,dataEnv 将不会被标记为可达和收集。
    • 对不起,'它仍然是垃圾收集'应该是'然后它将被垃圾收集'
    【解决方案2】:

    通常当我想将某些东西分配给全局环境时,我只是这样做

    varname <<- value
    

    【讨论】:

    • 当它从闭包内部移动到外部时,不会复制函数内部的环境吗?
    • 是的。就个人而言,我会接受 Usobi 的回应,但如果您想将该特定变量名称分配给全局环境(看起来就像您在提供的代码中所做的那样),这就是您要做的。 myEnv&lt;&lt;-dataEnv 将是与上面执行相同操作的代码。
    猜你喜欢
    • 1970-01-01
    • 2023-03-23
    • 2015-11-10
    • 2019-01-04
    • 2017-09-12
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多