In this connection, note the following > a4 <- 4 > plotThis <- bquote(alpha==.(a), list(a=a4)) > do.call(plot, list(1:10, main=do.call(expression, c(plotThis)))) > do.call(plot, list(1:10, main=do.call(expression, plotThis))) Error in do.call(expression, plotThis) : second argument must be a list
> ## Whereas plotThis has class "call", c(plotThis) has class "list" > class(plotThis) [1] "call" > class(c(plotThis)) [1] "list" > ## Thus, the following is possible: > do.call(plot, list(1:10, main=do.call(expression, list(plotThis)))) Marc Schwartz pointed out to me., some considerable time ago, that one could use bquote() and .() to create the elements of a list object whose elements can be plotted in parallel as required, e.g., for axis labels, thus: > plot(1:2, 1:2, xaxt="n") > arg1 <- bquote(""< .(x), list(x=1.5)) > arg2 <- bquote("">= .(x), list(x=1.5)) > axis(1, at=1:2, labels=do.call(expression, list(arg1, arg2))) For a unified approach to use of do.call(expression, ...), maybe one should use bquote() and .()? John Maindonald email: [EMAIL PROTECTED] phone : +61 2 (6125)3473 fax : +61 2(6125)5549 Centre for Mathematics & Its Applications, Room 1194, John Dedman Mathematical Sciences Building (Building 27) Australian National University, Canberra ACT 0200. On 18 Jul 2007, at 8:00 PM, [EMAIL PROTECTED] wrote: > From: Peter Dalgaard <[EMAIL PROTECTED]> > Date: 18 July 2007 1:39:50 AM > To: Deepayan Sarkar <[EMAIL PROTECTED]> > Cc: R Development Mailing List <[EMAIL PROTECTED]> > Subject: Re: [Rd] substitute and expression > > > Deepayan Sarkar wrote: >> On 7/16/07, Peter Dalgaard <[EMAIL PROTECTED]> 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. >> > Probably the correct solution is to use expression objects. More or > less > the entire reason for their existence is this sort of surprises. > > plot(y ~ x, data = list(x = 1:10, y = 1:10), main = > as.expression(substitute(alpha==a, list(a=2)))) > > I'm not going to investigate why this is necessary in connection with > plot(), but the core issue is probably > >> e <- quote(f(x)) ; e[[2]] <- quote(2+2) >> e > f(2 + 2) >> f <- quote(f(2+2)) >> identical(e,f) > [1] TRUE > > notice that since the two calls are identical, there is no way for > e to > detect that it was called with x replaced by an object of mode "call". > Or put differently, objects of mode call tend to lose their > "personality" in connection with computing on the language. > > > -- > O__ ---- Peter Dalgaard Ă˜ster Farimagsgade 5, Entr.B > c/ /'_ --- Dept. of Biostatistics PO Box 2099, 1014 Cph. K > (*) \(*) -- University of Copenhagen Denmark Ph: (+45) > 35327918 > ~~~~~~~~~~ - ([EMAIL PROTECTED]) FAX: (+45) > 35327907 ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel