On 6/04/2011 12:47 a.m., Deepayan Sarkar wrote:
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
Thanks very much for this explanation Deepayan. Part of my intention in
contributing to this thread was to have something explicit in the
archives for future reference, and your reply is excellent in that regard.
And many thanks for your work on lattice.
David Scott
--
_________________________________________________________________
David Scott Department of Statistics
The University of Auckland, PB 92019
Auckland 1142, NEW ZEALAND
Phone: +64 9 923 5055, or +64 9 373 7599 ext 85055
Email: d.sc...@auckland.ac.nz, Fax: +64 9 373 7018
Director of Consulting, Department of Statistics
______________________________________________
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.