Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

parent.env( x ) confusion

Tags:

r

I've read the documentation for parent.env() and it seems fairly straightforward - it returns the enclosing environment. However, if I use parent.env() to walk the chain of enclosing environments, I see something that I cannot explain. First, the code (taken from "R in a nutshell")

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

And the results:

[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"

How can we explain the "base" at the top and the "base" at the bottom? Also, how can we explain "package:PerformanceAnalytics" and "imports:PerformanceAnalytics"? Everything would seem consistent without the first two lines. That is, function chart.RelativePerformance is in the package:PerformanceAnalytics environment which is created by xts, which is created by zoo, ... all the way up (or down) to base and the empty environment.

Also, the documentation is not super clear on this - is the "enclosing environment" the environment in which another environment is created and thus walking parent.env() shows a "creation" chain?

Edit

Shameless plug: I wrote a blog post that explains environments, parent.env(), enclosures, namespace/package, etc. with intuitive diagrams.

like image 990
SFun28 Avatar asked Dec 26 '11 15:12

SFun28


1 Answers

1) Regarding how base could be there twice (given that environments form a tree), its the fault of the environmentName function. Actually the first occurrence is .BaseNamespaceEnv and the latter occurrence is baseenv().

> identical(baseenv(), .BaseNamespaceEnv)
[1] FALSE

2) Regarding the imports:PerformanceAnalytics that is a special environment that R sets up to hold the imports mentioned in the package's NAMESPACE or DESCRIPTION file so that objects in it are encountered before anything else.

Try running this for some clarity. The str(p) and following if statements will give a better idea of what p is:

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
}
like image 173
G. Grothendieck Avatar answered Sep 21 '22 12:09

G. Grothendieck