Why can't this R call object in an expression be evaluated? (subsetting vs extracting from a call object) -
i trying understand r expression
object, encountered difficulties.
code snippet:
a = 1 b = 2 x = expression(sin(a+b+1)) print(class(x[[1]][2])) eval(x[[1]][2])
results:
#//////////////////////////////////////////////////// x = expression(sin(a+b+1)) #//////////////////////////////////////////////////// print(class(x[[1]][2])) [1] "call" #//////////////////////////////////////////////////// x = expression(sin(a+b+1)) #//////////////////////////////////////////////////// print(class(x[[1]][2])) [1] "call" #//////////////////////////////////////////////////// eval(x[[1]][2]) error in eval(expr, envir, enclos) : attempt apply non-function 2: eval(expr, envir, enclos) 1: eval(x[[1]][2])
x[[1]][2]
call
object, why can't evaluated?
you should use [[
operator, , not [
.
a <- 1 b <- 2 eval(x[[1]][[2]]) ## [1] 4
this because you'd extract information language object, , not subset (look inside 2nd element, , not return subsequence consisting of 2nd element).
in other words, subsetting call
gives call
:
x[[1]][2] ## (a + b + 1)()
and because there no such function a+b+1
(in fact, result of a+b+1
's evaluation not function object), r throws error.
interestingly, if +
return function object, make sense:
"+" <- function(a, b) { function() print(":-)") } (a+b+1)() [1] ":-)"
on other hand, extracting element call object gives expression can evaluated:
x[[1]][[2]] + b + 1
(btw, expression call, here equivalent "+"(a, "+"(b, 1))
.
edit. more formally, call expression (sequence) of form:
(f, a1, ..., an),
which read as:
f(a1, ..., an).
thus, first element of sequence object used transform other elements output value.
here x[[1]]
equivalent to:
(sin, a+b+1)
or, in more detail,
(sin, (+, a, (+, b, 1))).
thus, x[[1]][2]
takes subsequence of above consisting of 2nd element , returns:
((+, a, (+, b, 1)))
(i.e. (a+b+1)()
- no args!). on other hand x[[1]][[2]]
extracts (looks inside) 2nd element , gives:
(+, a, (+, b, 1)),
i.e. a+b+1
(note 1 pair of parentheses less).
edit2: of exemplifies beauty , expressiveness of r language, @ least imho. let's study example in create call f1(f2(f3, f4), f3, f4)
, may represented sequence
(f1, (f2, f3, f4), f3, f4).
we have:
f <- function(...) invisible(null) f1 <- f; f2 <- f; f3 <- f; f4 <- f # sake of clarity below expr <- quote(f1(f2(f3, f4), f3, f4)) print(expr) ## f1(f2(f3, f4), f3, f4), i.e. (f1, (f2, f3, f4), f3, f4) print(expr[1:3]) ## f1(f2(f3, f4), f3), i.e. (f1, (f2, f3, f4), f3) print(expr[3:4]) ## f3(f4), i.e. (f3, f4) print(expr[3]) ## f3(), i.e. (f3) expr[2] ## f2(f3, f4)(), i.e. ((f2, f3, f4)) [subsetting!]
and different:
expr[[2]] ## f2(f3, f4), i.e. (f2, f3, f4) [extraction]
hope clarifies these issues little bit.
Comments
Post a Comment