等价于inside,attach等,以便在环境中工作?

问题描述

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

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()获取列表或数据框(而不是环境)“ ...”,并对“数据”副本进行相应的修改
  • <<-有两个问题:(1)使用它会导致CRAN检查中出现NOTE(我认为?找不到直接的证据,但是例如see here -也许只会发生这种情况)由于外观上是分配给本地未定义的符号,我想我可以将其放在包中并用--as-cran进行测试以确认...); (2)它将尝试在父环境中进行分配,该父环境在程序包上下文中[这是]将被锁定...

我想我可以按照Introduction to R第10.7节的说明使用闭包

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

这似乎令人费解(但我想还不错吗?),但是:

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

我缺少明显且惯用的东西吗?

解决方法

感谢@ 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(),但是我必须非常小心地正确捕获该表达式没有对其进行评估...

,

with()呢?从here

with(data,expr)

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

expr是要评估的表达式。

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

请注意,expr中的分配是在构建的环境中进行的,而不是在用户的工作空间中进行的。

with()返回求值的expr的值。


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