In R, exactly what causes an object of type (or character) to be evaluated?

After launch:

x <- as.name("aa") aa <- 2 

in R why not

 (x) 

return 2? And why not

 x <- as.name("aa") aa <- 3 get(get(x)) 

return 3?

I know that get () expects a string, but I do not understand why it does not evaluate x, find the string inside, and then get it. It seems to me that sometimes functions perform such an assessment of their arguments, and sometimes not. For example, in the second example, if you replace get (get (x)) with eval (x), eval () evaluates x to find the name, and then evaluates the name to find 3.

+5
source share
2 answers

I think the @joran answer is right, but maybe I will try to explain in a different way.

The function ( "in R is essentially an identical function. It repeats what you pass. It is almost as if it is not. There is no difference between what will be returned by these operators

 x #1 (x) #2 ((x)) #3 

The parentheses are just the value inside. You can add as many brackets as you want, and this will not change the return. The evaluator looks at ((x)) , see the outer bracket and knows how to simply return the value of the thing inside the bracket. So now he parses only (x) , and again he sees the outer bracket and just returns the value inside the bracket, which is equal to x . The brackets just go through, although the meaning is inside; they do not value it.

The bare value of x is the name (or character). The name is not uniquely associated with the value. The mapping between names and values ​​is different from the environment. Therefore, names must be evaluated in a specific context in order to obtain meaning. Consider these examples

 aa <- 5 dd <- data.frame(aa=20) x <- as.name("aa") foo <- function(x) {aa<-10; eval(x)} eval(x) # [1] 5 foo(x) # [1] 10 eval(x, dd) # [1] 20 

This behavior is really very desirable. This is what makes functions requiring a non-standard assessment, such as

 subset(mtcars, hp<100) 

When you use the R console, it behaves like REPL - it reads your input, evaluates it, prints it, and then waits for the next input. Please note that only one level of evaluation and evaluation occurs in the "current" environment. It does not recursively evaluate the return value from an expression. Therefore when you do

 x <- as.name("aa") x # identical to (x) # aa 

when the REPL goes to the evaluation step, it evaluates the name x , which points to the name aa . It. One level of assessment. The name aa not subsequently evaluated.

There is a note on the ?eval help page:

eval evaluates its first argument in the current scope before passing it to the evaluator

There is no "double" rating. It simply evaluates its parameters just like any other function in R. For examples

 aa <- 5 bar <- function(x) print(x) bar(aa+2) # [1] 7 

It prints "7", not "aa + 2", because the function checked its parameter before printing. It also explains the differences between the two.

 dd <- data.frame(bb=20) xx <- as.name("bb") eval(bb, dd) # Error in eval(bb, dd) : object 'bb' not found eval(xx, dd) # [1] 20 

In the first call to eval() R cannot evaluate bb in the current environment so that you get an error. But keep in mind that

 evalq(bb, dd) 

works because evalq does not try to evaluate the first parameter of the expression.

+5
source

Since the value of x not equal to 2, this is the character (or name) aa . However, if you are eval this:

 > eval(x) [1] 2 

Similarly, get(x) does not work at all (i.e. creates an error), because according to the documentation for get , the first argument should be an object name (given as a character string) , where it is supposed to distinguish it from the / character in brackets name.

get only works with a character argument:

  > get("aa") [1] 2 

And symbol (which I find less confusing than name ) is not the same thing:

 > identical("aa",as.name("aa")) [1] FALSE 

( as.name and as.symbol do the same.)

For a great explanation of “evaluating expressions” and “evaluating function arguments”, which I mentioned in the comment below, see @MrFlick's answer.

+10
source

All Articles