Why doesn't c pass a variable region through nested functions?

In R, if I create an environment and then use with to evaluate a function in that environment, the function usually has access to the variables. However, if I have a socket function, for some reason they go beyond. Can you explain to me why this is so?

Example:

Create a new environment with the variable x

 E = new.env(); E$x = c(1,2,3) 

Using with , I can print this variable:

 with(E, print(x)); #[1] 1 2 3 

But now, if I nested this function, it no longer works:

 printMe = function() { print(x); } with(E, printMe()) #Error in print(x) : object 'x' not found 

I know that I can make it work like this:

 printMe = function(x) { print(x); } with(E, printMe(x)) #[1] 1 2 3 

But I don't understand - if with creates an environment, why can't a nested function see x ? It works if you attach it:

 attach(E) printMe() #[1] 1 2 3 

I think I just missed something, but what is the recommended way to do this? Or, to ask your question in another way: why can't nested functions in with access free variables?

+5
source share
2 answers

R is lexically not covered by a dynamic region. The printMe environment is a global environment because it is defined in a global environment

 environment(printMe) <environment: R_GlobalEnv> 

So when you call:

 with(E, printMe()) 

The printMe function tries to find x locally. This is not true. He then tries to find x in his environment, which is a global environment, not a local with environment. He does not find it again, then he gives an error.

To illustrate this point, look that if you define printMe inside with , the printMe environment will be the local with environment, and it will find x :

 with(E,{ printMe <- function() { print(x) } print(environment(printMe)) printMe() }) <environment: 0x29785678> [1] 1 2 3 

Or you can change the printMe environment inside with :

 with(E, { environment(printMe) <- environment() printMe() }) [1] 1 2 3 

As for your second example, when you attach the E environment, you make the E (ie, x ) objects available to the global environment. Therefore, when you call printMe in this situation, it will look for x in the global environment, and since E connected, it will find it. That is why it works.

I had the same doubts as yours, so this question may help you: Environment in R, map and get .

It may also help: Understanding vocabulary in R

+4
source

Basically, when you use with , you do the same thing as

 printMe = function() { print(x); } local({ x=1:3 printMe() }) # Error in print(x) : object 'x' not found 

which also does not work. This is due to how free variables are allowed in the function. When you call printMe , it will look for the resolution of the variables in the window itself, then it looks in the parent frame where the function was defined (it does not look where the function was called). Here printMe defined in a global environment. However, x not defined in the global environment. If you do

 printMe = function() { print(x); } x=1:3 printMe() # [1] 1 2 3 

Then both x and printMe defined in the global environment, so it works. You can also change the environment of the printMe function

  environment(printMe) <- E printMe() # [1] 1 2 3 

or define a function in the same environment as with

 with(E,{printMe <- function() {print(x)}; printMe()}) # [1] 1 2 3 

The main thing is that it doesn’t matter from which environment you call the functions, it is important in which environments they were defined.

You might want to check out the advanced R functional programming material that conveys these properties.

+7
source

Source: https://habr.com/ru/post/1203224/


All Articles