Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

expression vs call

Tags:

r

expression

call

What is the difference between an expression and a call?

For instance:

func <- expression(2*x*y + x^2)
funcDx <- D(func, 'x')

Then:

> class(func)
[1] "expression"
> class(funcDx)
[1] "call"

Calling eval with envir list works on both of them. But Im curious what is the difference between the two class, and under what circumstances should I use expression or call.

like image 278
David Angyal Avatar asked Jan 11 '23 18:01

David Angyal


1 Answers

You should use expression when you want its capacity to hold more than one expression or call. It really returns an "expression list". The usual situation for the casual user of R is in forming arguments to ploting functions where the task is forming symbolic expressions for labels. R expression-lists are lists with potentially many items, while calls never are such. It's interesting that @hadley's Advanced R Programming suggests "you'll never need to use [the expression function]": http://adv-r.had.co.nz/Expressions.html. Parenthetically, the bquote function is highly useful, but has the limitation that it does not act on more than one expression at a time. I recently hacked a response to such a problem about parsing expressions and got the check, but I thought @mnel's answer was better: R selectively style plot axis labels

The strategy of passing an expression to the evaluator with eval( expr, envir= < a named environment or list>) is essentially another route to what function is doing. A big difference between expression and call (the functions) is that the latter expects a character object and will evaluate it by looking for a named function in the symbol table.

When you say that processing both with the eval "works", you are not saying it produces the same results, right? The D function (call) has additional arguments that get substituted and restrict and modify the result. On the other hand evaluation of the expression-object substitutes the values into the symbols.

There seem to be "levels of evaluation":

expression(mean(1:10))
# expression(mean(1:10))
 call("mean" , (1:10))
# mean(1:10)
 eval(expression(mean(1:10)))
# [1] 5.5
 eval(call("mean" , (1:10)))
# [1] 5.5

One might have expected eval(expression(mean(1:10))) to return just the next level of returning a call object but it continues to parse the expression tree and evaluate the results. In order to get just the unevaluated function call to mean, I needed to insert a quote:

eval(expression(quote(mean(1:10))))
# mean(1:10)
like image 199
IRTFM Avatar answered Jan 18 '23 05:01

IRTFM