[Rd] substitute and expression

Deepayan Sarkar deepayan.sarkar at gmail.com
Tue Jul 17 02:14:48 CEST 2007


On 7/16/07, Peter Dalgaard <p.dalgaard at biostat.ku.dk> wrote:
> Deepayan Sarkar wrote:
> > Hi,
> >
> > I'm trying to understand whether the use of substitute() is
> > appropriate/documented for plotmath annotation. The following two
> > calls give the same results:
> >
> >
> >> plot(1:10, main = expression(alpha == 1))
> >> do.call(plot, list(1:10, main = expression(alpha == 1)))
> >>
> >
> > But not these two:
> >
> >
> >> plot(1:10, main = substitute(alpha == a, list(a = 2)))
> >> do.call(plot, list(1:10, main = substitute(alpha == a, list(a = 2))))
> >>
> > Error in as.graphicsAnnot(main) : object "alpha" not found
> >
> > (as a consequence, xyplot(..., main = substitute(alpha)) doesn't
> > currently work.)
> >
> > On the other hand, this works:
> >
> >
> >> foo <- function(x) plot(1, main = x)
> >> foo(substitute(alpha))
> >>
> >
> > I'm not sure how to interpret ?plotmath; it says
> >
> >      If the 'text' argument to one of the text-drawing functions
> >      ('text', 'mtext', 'axis', 'legend') in R is an expression, the
> >      argument is interpreted as a mathematical expression...
> >
> > and uses substitute() in its examples, but
> >
> >
> >> is.expression(substitute(alpha == a, list(a = 1)))
> >>
> > [1] FALSE
> >
> I think you need to take plotmath out of the equation and study the
> difference between objects of mode "call" and those of mode
> "expression". Consider this:
>
>  > f <- function(...)match.call()
>  > do.call(f, list(1:10, main = substitute(alpha == a, list(a = 2))))
> function(...)match.call()
> (1:10, main = alpha == 2)
>  > do.call(list, list(1:10, main = substitute(alpha == a, list(a = 2))))
> Error in do.call(list, list(1:10, main = substitute(alpha == a, list(a =
> 2)))) :
>         object "alpha" not found
>
> The issue is that function ends up with an argument  alpha == 2 which it
> proceeds to evaluate (lazily), where a direct call sees
> substitute(.....). It is a general problem with the do.call mechanism
> that it effectively pre-evaluates the argument list, which can confuse
> functions that rely on accessing the original argument expression. Try,
> e.g., do.call(plot, list(airquality$Wind, airquality$Ozone)) and watch
> the axis labels.

Right. Lazy evaluation was the piece I was missing.

> Does it work if you use something like
>
>  main = substitute(quote(alpha == a), list(a = 2))?

Not for xyplot, though I haven't figured out why. Turns out this also
doesn't work:

> plot(y ~ x, data = list(x = 1:10, y = 1:10), main = substitute(alpha))
Error in as.graphicsAnnot(main) : object "alpha" not found

I'll take this to mean that the fact that substitute() works sometimes
(for plotmath) is an undocumented side effect of the implementation
that should not be relied upon.

-Deepayan



More information about the R-devel mailing list