R:功能 - 显示环境名称而不是该环境的内存地址?

Sat*_*ish 8 r

像内置函数一样显示函数内部环境名称的方法是什么?例如,当我输入函数:在基础包中可用时,我可以将环境视为"namespace:base".

mean

   function (x, ...) 
   UseMethod("mean")
   <bytecode: 0x0547f17c>
   **<environment: namespace:base>**
Run Code Online (Sandbox Code Playgroud)

但是,当我将一个函数附加到新创建的环境时,这里要访问函数(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>**
Run Code Online (Sandbox Code Playgroud)

为什么我会看到这种行为?为什么我不能在函数内部获取环境名称,就像R的内置函数以及各种R软件包中提供的函数一样?环境数据结构和.globalEnv环境之间是否存在搜索()

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

谢谢

Mai*_*ura 6

如果我没记错的话,包和名称空间的环境名称是在C级别分配的。因此,用户创建的环境不会显示名称。即使有一个(误称)基本函数,您也无法在R中设置环境名称environmentName()。它只会返回在C级分配的名称。它实际上仅适用于包和名称空间,不适用于其他环境。


Ste*_*ers 5

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

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

environmentName(e)
## [1] "xyzzy"
Run Code Online (Sandbox Code Playgroud)


mas*_*opi 3

您可以使用我最近发布的包环境名称来解决此问题。

在您的示例中,如果您使用包的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))
Run Code Online (Sandbox Code Playgroud)

输出是:

[1] "e1"
Run Code Online (Sandbox Code Playgroud)

在 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))
Run Code Online (Sandbox Code Playgroud)

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

R_GlobalEnv R_GlobalEnv R_GlobalEnv 
       "e1"        "e2"        "e3"
Run Code Online (Sandbox Code Playgroud)

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

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

> f
function(x) {
       x + z 
    }
<environment: 0x0000000013f15870>
> environment_name("<environment: 0x0000000013f15870>")
[1] "e1"
Run Code Online (Sandbox Code Playgroud)