[R] lattice::xyplot() with one factor for points and another for lines

Deepayan Sarkar deepayan.sarkar at gmail.com
Sat Aug 21 18:53:06 CEST 2010


On Sat, Aug 21, 2010 at 5:58 AM, Dennis Murphy <djmuser at gmail.com> wrote:
> Hi:
>
> In lattice, how does one handle separate graphical behavior for two
> different factors? In the xyplot below, the objective is to use the levels
> of one factor to distinguish corresponding shapes and colors, and the levels
> of the other factor to perform level-wise loess smooths.
>
> # Illustrative data:
> d <- data.frame(time = rep(1:8, each = 6), val = rnorm(48),
>                gp1 = factor(rep(1:6, 8)),
>                gp2 = factor(rep(rep(c('A', 'B'), each = 3), 8)))
>
> Based on the code from the Lattice book, p. 160, I set up the following:
>
> mypch <- 1:6
> mycol <- 1:6
>
> with(d,
> xyplot(val ~ time,
>       panel = function(x, y, ..., groups, subscripts) {
>                 pch <- mypch[gp1[subscripts]]
>                 col <- mycol[gp1[subscripts]]
>                 grp <- gp2
>                 panel.xyplot(x, y, pch = pch, col = col)
>                 panel.loess(x, y, groups = grp, lty = 1,
>                             col.line = c('blue', 'red'))
>          }
>      )  )
>
> As stated in the book, the with() wrapper allows one to use variable names
> within the panel function. I was hoping to get away with using both groups
> and subscripts in the panel function and fake my way through, but no luck. I
> get 90% of what I want: the points are plotted correctly, but only one loess
> line shows up instead of two. I put groups before the ellipsis in the
> argument list, defined groups = gp2 in the function call and a couple of
> other things, but got the same result.

You are on the right track, except that panel.loess is not "groups-aware".

I would do something like

with(d,
     xyplot(val ~ time,
            pch = mypch, col = mycol,
            lty = 1, col.line = c('blue', 'red'),
            subscripts = TRUE,
            panel = function(x, y, ..., groups) {
                panel.superpose(x, y, ..., groups = gp1, panel = panel.points)
                panel.superpose(x, y, ..., groups = gp2, panel = panel.loess)
            }))

The first call inside the panel function could be simpler, but this
makes the intention clearer.

-Deepayan



More information about the R-help mailing list