9

像内置函数一样显示函数内部环境名称的方法是什么?例如,当我键入 function:mean available in base package 时,我可以将环境视为“namespace:base”。

mean

   function (x, ...) 
   UseMethod("mean")
   <bytecode: 0x0547f17c>
   **<environment: namespace:base>**

但是,当我将一个函数附加到新创建的环境时,在这里访问函数 (f) 内的自由变量 (z) 的值时,它会自动驻留在 .GlobalEnv 环境中,并且环境的名称不会显示在功能,但看到(e1)环境的内存地址“0x051abd60”。

     e1 <- new.env()
     e1$z <- 10
     f <- function(x) {
           x + z 
      }
     environment(f) = e1
     f

               function(x) {
                    x + z 
               }
               **<environment: 0x051abd60>**

为什么我会看到这种行为?为什么我不能在函数中获取我的环境名称,就像 R 的内置函数以及各种 R 包中可用的函数一样?search() 提供的环境数据结构和 .GlobalEnv 环境之间是否有区别

任何指向这种行为背后的动机的指针都将受到高度赞赏。

谢谢

4

4 回答 4

9

您可以使用 设置环境名称attr,如下所示:

e <- new.env()
attr(e, "name") <- "xyzzy"

environmentName(e)
## [1] "xyzzy"
于 2017-12-01T22:01:36.507 回答
6

如果我没记错的话,包和命名空间的环境名称是在 C 级别分配的。因此,用户创建的环境不会显示名称。你不能在 R 中设置环境名称,即使有一个名为environmentName(). 它只会返回在 C 级别分配的名称。它实际上只适用于包和命名空间,而不适用于其他环境。

于 2012-10-02T21:47:15.973 回答
3

大多数环境没有名称 - 环境的名称是环境的特殊属性,而不是指向该环境的对象的名称。例如,在以下情况下,您希望 f 的环境的“名称”是什么?

e1 <- new.env()
e1$z <- 10
e2 <- e1
e3 <- e1

f <- function(x) {
  x + z 
}
environment(f) <- e1

identical(e1, e2)
identical(e1, e3)
于 2012-10-08T14:42:27.040 回答
3

您可以使用我开发的最近发布的包envnames作为解决此问题的方法。

在您的示例中,如果您使用包的environment_name()函数来检索f()您将获得的函数环境"e1",而不是""使用内置函数获得的环境environmentName(),即:

library(envnames)
e1 <- new.env()
e1$z <- 10
f <- function(x) {
   x + z 
}
environment(f) = e1
environment_name(environment(f))

输出是:

[1] "e1"

在 Hadley 给出的示例中,许多环境指向同一个环境,您可以在命名数组中获得所有这些环境名称:

library(envnames)
e1 <- new.env()
e1$z <- 10
e2 <- e1
e3 <- e1

f <- function(x) {
  x + z 
}
environment(f) <- e1
environment_name(environment(f))

其中输出包括每个环境的位置作为返回数组的名称属性:

R_GlobalEnv R_GlobalEnv R_GlobalEnv 
       "e1"        "e2"        "e3"

最后,由于您提到看到环境的内存地址并不能告诉我们太多关于我们正在谈论的用户定义的环境,您可以使用内存地址作为environment_name()函数的输入参数来获取环境的名称(或环境)与内存地址相关联

以下代码片段和输出说明了这一点(代码在的单个环境示例中运行):

> f
function(x) {
       x + z 
    }
<environment: 0x0000000013f15870>
> environment_name("<environment: 0x0000000013f15870>")
[1] "e1"
于 2019-06-27T08:03:23.103 回答