Re: [R] still trying to wrap xyplot - ignore previous

From: Deepayan Sarkar <deepayan.sarkar_at_gmail.com>
Date: Fri, 08 Jun 2007 13:32:54 -0700

On 6/8/07, Zack Weinberg <zackw_at_panix.com> wrote:
> As you may not be surprised to hear, no sooner did I post the previous
> message than I realized I had a really dumb mistake. I've now gotten
> a bit farther but am still stuck. New code:
>
> graph <- function (x, data, groups, xlab) {
> pg <- function(x, y, group.number, ...) fnord
> body(pg) <- substitute({
> panel.xyplot(x, y, ..., group.number=group.number)
> panel.text(2, unique(y[x==2]),
> levels(G)[group.number],
> pos=4, cex=0.5)
> }, list(G=eval(substitute(groups), data, parent.frame())))
>
> print(xyplot(x, data=data, groups=substitute(groups),
> type='l',
> ylab=list(cex=1.1, label='Mean RT (ms)'),
> xlab=list(cex=1.1, label=xlab),
> scales=list(
> x=list(alternating=c(1,1), tck=c(1,0)),
> y=list(alternating=c(1,0))
> ),
> panel=panel.superpose,
> panel.groups=pg
> ))
> }
>
> Questions:
> 1) The "groups=substitute(groups)" bit (in the call to xyplot) still
> doesn't work. As far as I can tell, xyplot wants the *symbol* which
> is the name of the factor (in the data frame) to group by.
> The above seems to wind up passing it the symbol "groups", which
> causes the prepanel function to barf. I have not been able to find
> any way to evaluate one layer of "groups" to get me the symbol passed
> in, rather than the value of that symbol. Am I right? How do I give
> it what it wants?
>
> 2) Why do I have to do that stupid dance with replacing the body of
> pg? The documentation leads me to believe this is a lexically scoped
> language, shouldn't it be able to pick G out of the enclosing frame?

This is all a consequence of non-standard evaluation, which can be a real pain sometimes. I don't have a solution that is "intuitive", but I don't think there is one. This is what I would do (and there are examples of this in lattice, e.g. see lattice:::dotplot.formula):

graph <- function (x, data, groups, xlab) {

    ## set up g and pg (lexical scope does work here)     g <- eval(substitute(groups), data, parent.frame())     pg <- function(x, y, group.number, ...) {

        panel.xyplot(x, y, ..., group.number=group.number)
        panel.text(2, unique(y[x==2]),
                   levels(g)[group.number],
                   pos=4, cex=0.5)

    }

    ## modify and evaluate call without
    ## actually evaluating 'groups'
    ccall <- match.call()
    ccall[[1]] <- quote(xyplot)
    fixed.args <-

        list(type='l',
             ylab=list(cex=1.1, label='Mean RT (ms)'),
             xlab=list(cex=1.1, label=xlab),
             scales=list(
             x=list(alternating=c(1,1), tck=c(1,0)),
             y=list(alternating=c(1,0))
             ),
             panel="panel.superpose",
             panel.groups = pg)

    ccall[names(fixed.args)] <- fixed.args     eval.parent(ccall)
}

sm <- data.frame(x = 1:10, y = rnorm(10), a = gl(3, 1, 10)) graph(y ~ x, sm, a, "foo")

This is a different approach from the one you were trying, but I think it makes more sense once you get used to it. Note that there are some subtle things going on here. The 'g' used by pg() is available only because the relevant environment is stored and is accessible through the "trellis" object:

> foo <- graph(y ~ x, sm, a, "foo")
> ls(environment(foo$panel.args.common$panel.groups))

[1] "ccall"      "data"       "fixed.args" "g"          "groups"
[6] "pg"         "x"          "xlab"

Hope this helps,

-Deepayan



R-help_at_stat.math.ethz.ch 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. Received on Fri 08 Jun 2007 - 20:39:21 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 Fri 08 Jun 2007 - 21:32:13 GMT.

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