【问题标题】:equivalent of within(), attach() etc. for working within an environment?相当于 inside()、attach() 等在环境中工作?
【发布时间】:2020-08-16 00:54:16
【问题描述】:

我想在搜索路径中添加一个环境,并在有限的代码块中修改该环境中变量的值,而不必在每次引用变量时都指定环境的名称:例如,给定环境

ee <- list2env(list(x=1,y=2))

现在我想做类似的事情

ee$x <- ee$x+1
ee$y <- ee$y*2
ee$z <- 6

但没有将ee$ 附加到所有内容(或使用assign("x", ee$x+1, ee) ...等):类似

in_environment(ee, {
    x <- x+1
    y <- y+2
    z <- 6
})

我能想到的大多数解决方案都是明确设计的不是为了修改环境,例如

  • ?attach: "实际上并没有附加数据库。而是一个新的环境 在搜索路径上创建..."
  • within():采用列表或数据框(不是环境)“......并对‘数据’的副本进行相应的修改”
  • &lt;&lt;- 有两个问题:(1) 使用它会在 CRAN 检查中引起注意(我认为?找不到直接的证据,但例如 see here — 这可能只是因为外观而发生分配给本地未定义的符号?我想我可以把它放在一个包中并用--as-cran对其进行测试以确认...); (2) 它将尝试在父环境中分配,而在包上下文中 [this is] 将被锁定...

我想我可以使用Introduction to R 第 10.7 节中描述的闭包

clfun <- function() {
   x <- 1
   y <- 2
   function(...) {
      x <<- x + 1   
      y <<- y * 2
   }
}
myfun <- clfun()

这看起来很复杂(但我想还不错吧?)但是:

  • 仍会出现问题 #1(CRAN 检查?)。
  • 我认为 (??) 它不适用于环境中尚不存在的变量(为此需要明确的 assign() ...)
  • 不允许选择在哪个环境中运行 - 它必须在封闭环境中工作,而不是在任意环境ee

我是否遗漏了一些明显和惯用的东西?

【问题讨论】:

  • with() 怎么样? Here 它说 with 可以将环境作为其参数?不过,我真的不知道你在做什么,所以如果这与你正在寻找的内容不接近,我很抱歉。
  • 你可能是对的!
  • @Nuclear03020704,如果您想将此作为答案发布,我会接受。

标签: r closures


【解决方案1】:

感谢@Nuclear03020704!我认为with() 是我一直想要的;我错误地假设它也会创建环境的本地副本,但只有在 data 参数还不是环境时才会这样做。

ee <- list2env(list(x=1,y=2))
with(ee, {
    x <- x+1
    y <- y+2
    z <- 6
})

正是我想要的。


刚刚有了另一个想法,它似乎也有一些缺点:使用大的eval 子句。与其把我的问题变成一长串令人不满意的解决方案,我将在此处添加。

myfun <- function() {
    eval(quote( {
        x <- x+1
        y <- y*2
        z <- 3
    }), envir=ee)
}

这似乎确实有效,但也看起来很奇怪/神秘!我不想考虑向使用 R 不到 10 年的人解释它......我想我可以基于此写一个 in_environment(),但我必须非常小心地正确捕捉表达式而不进行评估它...

【讨论】:

  • 捕捉环境并没有那么棘手,不是吗?例如我认为in_environment &lt;- function(ee, code) {eval(substitute(code), envir=ee, enclos=parent.frame())} 应该做你想做的(除非我错过了什么)
  • 但我认为这不会通过 CRAN 检查。当包代码使用非标准评估时,这些检查似乎不喜欢它。猜猜它应该是仅供用户使用的便利。未在未明确定义的公式中的符号通常会导致问题。但如果有人知道反例,我会很好奇。
  • globalVariables() 应该解决这个问题(尽管 Martin Maechler 不喜欢它并且更喜欢 x &lt;- y &lt;- NULL (在这种情况下不起作用)......不知道为什么...... .
【解决方案2】:

with() 呢?来自here,

with(data, expr)

data 是用于构建环境的数据。对于默认的 with 方法,这可能是环境、列表、数据框或整数。

expr 是要计算的表达式。

with 是一个通用函数,它在由数据构建的本地环境中评估expr。该环境将调用者的环境作为其父环境。这对于简化对建模函数的调用很有用。 (注意:如果data 已经是一个环境,那么这将与其现有的父级一起使用。)

请注意,expr 中的分配发生在构建的环境中,而不是在用户的工作区中。

with() 返回评估的expr 的值。


ee <- list2env(list(x=1,y=2))
with(ee, {
    x <- x+1
    y <- y+2
    z <- 6
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 2011-04-07
    • 2015-01-23
    相关资源
    最近更新 更多