To illustrate lexical reach, consider the following:
First create an environment for the sandbox, only to avoid the so-called R_GlobalEnv:
sandbox <-new.env()
Now we put two functions in it: f , which looks for a variable named x ; and g , which defines local x and calls f :
sandbox$f <- function() { value <- if(exists("x")) x else "not found." cat("This is function f looking for symbol x:", value, "\n") } sandbox$g <- function() { x <- 123 cat("This is function g. ") f() }
Technical information: entering functions in the console causes the environment to be set to R_GlobalEnv , so we manually force the f and g shells to correspond to the environment in which they "belong":
environment(sandbox$f) <- sandbox environment(sandbox$g) <- sandbox
Call g . Local variable x=123 not found f :
> sandbox$g() This is function g. This is function f looking for symbol x: not found.
Now we create x in the global environment and call g . The f function will look for x first in the sandbox, and then in the parent slot of the sandbox, which turns out to be R_GlobalEnv:
> x <- 456 > sandbox$g() This is function g. This is function f looking for symbol x: 456
To make sure that f searches for x first in its application, we can put x there and call g :
> sandbox$x <- 789 > sandbox$g() This is function g. This is function f looking for symbol x: 789
Conclusion: A character search in R follows an environment chain, and not with evaluation frames created during the execution of nested function calls.
EDIT: just add a link to this very interesting Martin Morgan answer on parent.frame() vs parent.env()