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 -Deepayan
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. Does it work if you use something like main = substitute(quote(alpha == a), list(a = 2))?
On 7/16/07, Deepayan Sarkar <deepayan.sarkar at gmail.com> 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.)If your question is really about do.call then use the quote = TRUE argument. Then both of the above work: plot(1:10, main = substitute(alpha == a, list(a = 2))) do.call(plot, list(1:10, main = substitute(alpha == a, list(a = 2))), quote = TRUE) plot(1:10, main = expression(alpha == 1)) do.call(plot, list(1:10, main = expression(alpha == 1)), quote = TRUE) Another possibility is just to make sure you are passing an expression so that the first one would become: plot(1:10, main = substitute(alpha == a, list(a = 2))) do.call(plot, list(1:10, main = as.expression(substitute(alpha == a, list(a = 2)))))> > 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 am not sure what examples you are referring to but if you read the Value section in ?substitute it does say that substitute typically returns call objects but may return a name object and in principle can return others too so they need not be expressions.