Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inconsistency with R's Global Environment in a function call

Tags:

r

I was playing around with R and noticed some inconsistencies with the Global Environment surrounding function calls differing from the actual global environment.

Consider the following:

> test = function () 
+ {
+     print(environmentName(as.environment(-1)))
+     print(ls(as.environment(-1)))
+     print(environmentName(.GlobalEnv))
+     print(ls(.GlobalEnv))
+     as.environment(-1)
+ }
> foo = 1
> ls()
[1] "foo"  "test"
> test()
[1] ""
[1] "doTryCatch" "expr"       "handler"    "name"       "parentenv" 
[1] "R_GlobalEnv"
[1] "foo"  "test"
<environment: R_GlobalEnv>

Within the function call, as.environment(-1) returns an environment that claims it is <environment: R_GlobalEnv> but when calling environmentName on said environment, its name is an empty character. Furthermore, the contents of it differ from what is in the true global environment. What exactly is going on here?

I first noticed the error using mget within a call, as a variable defined globally could not be found. This seems counter-intuitive because normally when referencing a variable within a function, R will search upwards in the enclosing environments until it finds a definition for a variable, including the global environment.

like image 550
Jon Claus Avatar asked Mar 03 '14 16:03

Jon Claus


People also ask

What is an R environment?

The environment is a virtual space that is triggered when an interpreter of a programming language is launched. Simply, the environment is a collection of all the objects, variables, and functions. Or, Environment can be assumed as a top-level object that contains the set of names/variables associated with some values.

What is the parent environment of a function R?

The parent environment of a function is the environment in which the function was created. If a function was created in the execution environment (for example, in the global environment), then the environment in which the function was called will be the same as the environment in which the function was created.


1 Answers

This is a consequence of lazy evaluation:

test <- function () {
  e <- as.environment(-1)

  list(
    lazy = ls(as.environment(-1)), 
    eager = ls(envir = e)
  )
}

foo <- 1
test()
#> $lazy
#> [1] "doTryCatch" "expr"       "handler"    "name"       "parentenv" 
#> 
#> $eager
#> [1] "foo"  "test"
like image 156
hadley Avatar answered Oct 03 '22 15:10

hadley