[R] substitute question

Thomas Lumley tlumley at u.washington.edu
Fri Mar 19 02:27:20 CET 2004


On Thu, 18 Mar 2004, Gabor Grothendieck wrote:

>
>
> I don't think I expressed myself very well on that.
>
> Looking at what we get from the example:
>
> > z <- substitute(substitute(expression(f),list(a=quote(b))),list(f=f))
>
> > z
> substitute(expression(function ()
> {
>     a + 1
> }), list(a = quote(b)))
>
> > class(z);mode(z);typeof(z)
> [1] "call"
> [1] "call"
> [1] "language"
>
>
> we see that the function seems to be expanded correctly and
> the statement does produce a call object.  However,
> applying eval one, two or three times does not give what
> you would think if you looked at z above.

Maybe we didn't express ourselves well enough.

Looking at z above isn't enough.  z is a call to substitute().
Its first operand is an expression. The expression contains a single term,
which is a function.

If you typed
notz<- quote(substitute(expression(function ()
 {
     a + 1
 }), list(a = quote(b))))

you would obtain something that deparsed the same as z, and so looked the
same, but was actually different.  In notz the first operand of substitute
is an expression containing multiple terms, which if evaluated would
return a function.

substitute() goes though this expression and checks each term to see if it
is `a`. In z there is only one term and it isn't `a`.  In notz there is
(after sufficient recursion) an `a` and it gets replaced.

So

> z[[2]][[2]]
function ()
{
    a + 1
}
> notz[[2]][[2]]
function() {
    a + 1
}

are the respective operands, and they still look the same. But

> mode(z[[2]][[2]])
[1] "function"
> mode(notz[[2]][[2]])
[1] "call"
> length(z[[2]][[2]])
[1] 1
> length(notz[[2]][[2]])
[1] 4

and if we try to find the actual `a` in there
> notz[[2]][[2]][[3]][[2]][[2]]
a
> z[[2]][[2]][[3]][[2]][[2]]
Error in z[[2]][[2]][[3]] : object is not subsettable
>


	-thomas




More information about the R-help mailing list