Re: [Rd] substitute and expression

From: Peter Dalgaard <P.Dalgaard_at_biostat.ku.dk>
Date: Tue, 17 Jul 2007 17:39:50 +0200

Deepayan Sarkar wrote:

> 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. > 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
~~~~~~~~~~ - (p.dalgaard_at_biostat.ku.dk)                  FAX: (+45) 35327907

______________________________________________
R-devel_at_r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Received on Tue 17 Jul 2007 - 16:55:37 GMT

Archive maintained by Robert King, hosted by the discipline of statistics at the University of Newcastle, Australia.
Archive generated by hypermail 2.2.0, at Tue 17 Jul 2007 - 17:36:42 GMT.

Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel. Please read the posting guide before posting to the list.