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