On Tue, Apr 5, 2011 at 6:12 AM, David Scott <d.sc...@auckland.ac.nz> wrote:
[...] > I am not sure where I read it and I can't find it again, but my > understanding is that expressions using bquote with lattice need to be > enclosed in as.expression() to work. That is in contrast to what happens in > base graphics. > > Here is a simple example. > > a <- 2 > plot(1:10, a*(1:10), main = bquote(alpha == .(a))) > require(lattice) > xyplot(a*(1:10)~ 1:10, main = bquote(alpha == .(a))) > xyplot(a*(1:10)~ 1:10, main = as.expression(bquote(alpha == .(a)))) > > Which produces: > >> a <- 2 >> plot(1:10, a*(1:10), main = bquote(alpha == .(a))) >> require(lattice) > Loading required package: lattice >> xyplot(a*(1:10)~ 1:10, main = bquote(alpha == .(a))) > Error in trellis.skeleton(formula = a * (1:10) ~ 1:10, cond = list(c(1L, : > object 'alpha' not found >> xyplot(a*(1:10)~ 1:10, main = as.expression(bquote(alpha == .(a)))) > > Using expression() rather than as.expression() doesn't produce the desired > affect. Try it yourself. > > As to why this is the case ..... Let's see: ?xyplot says 'main': Typically a character string or expression describing the main title to be placed on top of each page. [...] So, lattice is fairly explicit, by R standards, in requiring 'main' to be "character" or "expression". On the other hand, ?title says The labels passed to 'title' can be character strings or language objects (names, calls or expressions), or [...] so it additionally accepts "names" and "calls". Now, we have > a <- 2 > foo <- bquote(alpha == .(a)) > foo # Looks OK alpha == 2 > mode(foo) # But [1] "call" > is.expression(foo) # not an expression [1] FALSE > is.expression(expression(foo)) ## YES, but [1] TRUE > expression(foo) ## not what we want expression(foo) > is.expression(as.expression(foo)) [1] TRUE > as.expression(foo) ## This IS what we want expression(alpha == 2) So I submit that lattice is behaving exactly as suggested by its documentation. Now you would naturally argue that this is hiding behind technicalities, and if "call" objects work for plot(), it should work for lattice as well. But watch this: > plot(1:10, main = foo) # works perfectly > arglist <- list(1:10, main = foo) > arglist # Looks like what we want [[1]] [1] 1 2 3 4 5 6 7 8 9 10 $main alpha == 2 > do.call(plot, arglist) Error in as.graphicsAnnot(main) : object 'alpha' not found ...which I would say is "unexpected" behaviour, if not a bug. The moral of the story is that unevaluated calls are dangerous objects (try this one out for fun: foo <- bquote(q(.(x)), list(x = "no")) do.call(plot, list(1:10, main = foo)) ), and carrying them around is not a good idea. Lattice does use the do.call paradigm quite a bit, and I think it might be quite difficult to fix it up to handle non-expression language objects (which will still not fix the type of problem shown above). -Deepayan ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.