Understanding environments
Besides the function name, body, and formal arguments, the environment is another basic component of a function. In a nutshell, the environment is where R manages and stores different types of variables. Besides the global environment, each function activates its environment whenever a new function is created. In this recipe, we will show you how the environment of each function works.
Getting ready
Ensure that you completed the previous recipes by installing R on your operating system.
How to do it...
Perform the following steps to work with the environment:
- First, you can examine the current environment with the
environment
function:>environment() <environment: R_GlobalEnv>
- You can also browse the global environment with
.GlobalEnv
andglobalenv
:> .GlobalEnv <environment: R_GlobalEnv> >globalenv() <environment: R_GlobalEnv>
- You can compare the environment with the
identical
function:>identical(globalenv(), environment()) [1] TRUE
- Furthermore, you can create a new environment as follows:
>myenv<- new.env() >myenv <environment: 0x0000000017e3bb78>
- Next, you can find the variables of different environments:
>myenv$x<- 3 >ls(myenv) [1] "x" >ls() [1] "myenv" >x Error: object 'x' not found
- At this point, you can create an
addnum
function and useenvironment
to get the environment of the function:>addnum<- function(x, y){ + x+y + } >environment(addnum) <environment: R_GlobalEnv>
- You can also determine that the environment of a function belongs to the package:
>environment(lm) <environment: namespace:stats>
- Moving on, you can print the environment within a function:
>addnum2<- function(x, y){ + print(environment()) + x+y + } >addnum2(2,3) <environment: 0x0000000018468710> [1] 5
- Furthermore, you can compare the environment inside and outside a function:
>addnum3<- function(x, y){ + func1<- function(x){ + print(environment()) + } + func1(x) + print(environment()) + x + y + } >addnum3(2,5) <environment: 0x000000001899beb0> <environment: 0x000000001899cc50> [1] 7
How it works...
We can regard an R environment as a place to store and manage variables. That is, whenever we create an object or a function in R, we add an entry to the environment. By default, the top-level environment is the R_GlobalEnv
global environment, and we can determine the current environment using the environment function. Then, we can use either .GlobalEnv
or globalenv
to print the global environment, and we can compare the environment with the identical
function.
Besides the global environment, we can actually create our environment and assign variables into the new environment. In the example, we created the myenv
environment and then assigned x <- 3
to myenv
by placing a dollar sign after the environment name. This allows us to use the ls
function to list all variables in myenv
and global environment. At this point, we find x
in myenv
, but we can only find myenv
in the global environment.
Moving on, we can determine the environment of a function. By creating a function called addnum
, we can use environment
to get its environment. As we created the function under global environment, the function obviously belongs to the global environment. On the other hand, when we get the environment of the lm
function, we get the package name instead. That means that the lm
function is in the namespace of the stat
package.
Furthermore, we can print out the current environment inside a function. By invoking the addnum2
function, we can determine that the environment
function outputs a different environment name from the global environment. That is, when we create a function, we also create a new environment for the global environment and link a pointer to its parent environment. To further examine this characteristic, we create another addnum3
function with a func1
nested function inside. At this point, we can print out the environment inside func1
and addnum3
, and it is possible that they have completely different environments.
There's more...
To get the parent environment, we can use the parent.env
function. In the following example, we can see that the parent environment of parentenv
is R_GlobalEnv
:
>parentenv<- function(){ + e <- environment() + print(e) + print(parent.env(e)) + } >parentenv() <environment: 0x0000000019456ed0> <environment: R_GlobalEnv>