parent.env(x)混乱

SFu*_*n28 10 r

我已经阅读了parent.env()的文档,看起来相当简单 - 它返回了封闭的环境.但是,如果我使用parent.env()来处理封闭环境链,我会看到一些我无法解释的东西.首先,代码(摘自"R简而言之")

library( PerformanceAnalytics )
x = environment(chart.RelativePerformance)
while (environmentName(x) != environmentName(emptyenv())) 
{ 
    print(environmentName(parent.env(x)))
    x <- parent.env(x)
}
Run Code Online (Sandbox Code Playgroud)

结果如下:

[1] "imports:PerformanceAnalytics"
[1] "base"
[1] "R_GlobalEnv"
[1] "package:PerformanceAnalytics"
[1] "package:xts"
[1] "package:zoo"
[1] "tools:rstudio"
[1] "package:stats"
[1] "package:graphics"
[1] "package:utils"
[1] "package:datasets"
[1] "package:grDevices"
[1] "package:roxygen2"
[1] "package:digest"
[1] "package:methods"
[1] "Autoloads"
[1] "base"
[1] "R_EmptyEnv"
Run Code Online (Sandbox Code Playgroud)

我们如何解释顶部的"基础"和底部的"基础"?另外,我们如何解释"package:PerformanceAnalytics"和"imports:PerformanceAnalytics"?没有前两行,一切看起来都是一致的.也就是说,函数chart.RelativePerformance在包中:PerformanceAnalytics环境由xts创建,它由zoo创建,......一直向上(或向下)到base和空环境.

此外,文档对此并不十分清楚 - "封闭环境"是创建另一个环境的环境,因此行走的parent.env()显示了"创建"链?

编辑

无耻的插件:我写了一篇博文,用直观的图解释环境,parent.env(),附件,命名空间/包等.

G. *_*eck 5

1)关于怎么base可能有两次(假设环境形成一棵树),它是environmentName功能的错误.实际上第一次出现是.BaseNamespaceEnv,后一次出现baseenv().

> identical(baseenv(), .BaseNamespaceEnv)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

2)关于imports:PerformanceAnalytics这是一个特殊的环境,R设置为保存包的NAMESPACE或DESCRIPTION文件中提到的导入,以便在其他任何东西之前遇到它中的对象.

尝试运行它以获得一些清晰度.在str(p)与下面if的语句会给出什么更好的主意p是:

library( PerformanceAnalytics )
x <- environment(chart.RelativePerformance)
str(x)
while (environmentName(x) != environmentName(emptyenv())) { 
    p <- parent.env(x)
    cat("------------------------------\n")
    str(p)
    if (identical(p, .BaseNamespaceEnv)) cat("Same as .BaseNamespaceEnv\n")
    if (identical(p, baseenv())) cat("Same as baseenv()\n")
    x <- p
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*ien 3

结果中的前几项提供了 R 用于搜索具有命名空间的包中的函数中使用的变量的规则的证据。来自R-ext 手册

命名空间控制包中函数使用的变量的搜索策略。如果在本地找不到,R 首先搜索包命名空间,然后是导入,然后是基本命名空间,然后是正常搜索路径。

稍微详细说明一下,看一下前几行chart.RelativePerformance

head(body(chart.RelativePerformance), 5)
# {
#     Ra = checkData(Ra)
#     Rb = checkData(Rb)
#     columns.a = ncol(Ra)
#     columns.b = ncol(Rb)
# }
Run Code Online (Sandbox Code Playgroud)

chart.RelativePerformance评估对 的调用时,每个符号(无论是checkData第 1 行还是ncol第 3 行)都需要在搜索路径上的某个位置找到。以下是检查的前几个封闭环境:

  • 首先是namespace:PerformanceAnalytics. checkData在那里找到,但ncol没有。

  • 下一站(也是结果中列出的第一个位置)是imports:PerformanceAnalytics。这是在包文件中指定为导入的函数列表NAMESPACEncol这里也没有找到。

  • 环境base命名空间(ncol将在其中找到)是继续正常搜索路径之前的最后一站。几乎所有 R 函数都会使用某些base函数,因此此停止可确保该功能不会被全局环境或其他包中的对象破坏。(R 的设计者本可以让包作者base在其NAMESPACE文件中显式导入环境,但添加此默认传递base似乎确实是更好的设计决策。)