[R] indexing within panels in xyplot

Deepayan Sarkar deepayan.sarkar at gmail.com
Tue Feb 21 19:32:09 CET 2006


On 2/21/06, Sebastian Luque <spluque at gmail.com> wrote:
> "Deepayan Sarkar" <deepayan.sarkar at gmail.com> wrote:
>
> [...]
>
> > Well, there are exceptions to this rule, but generally x and y, when
> > they are passed on to the panel function, are _already_ subsetted, so
> > x[subscripts] makes absolutely no sense. Note how your panel function
> > calls
>
> > panel.xyplot(x, y, ...)
>
> > without referring to subscripts at all. The subscripts argument is
> > there for other variables (e.g. if you were drawing confidence
> > intervals, and had a separate vector in your data specifying the
> > interval lengths). In your case, there are no other variables
> > involved, so just get rid of the subscripts.
>
> Thanks Deepayan, I was indeed quite confused about this.
>
> I realized I needed to limit the fitted line to the range of x values the
> line is fit to, so I changed to panel.curve:
>
> ---<---------------cut here---------------start-------------->---
> xyplot(y ~ x | facA, groups = facB, data = toydf,
>        panel.groups = function(x, y, ...) {
>          panel.xyplot(x, y, ...)
>          lindx <- which(y == max(y, na.rm = TRUE))
>          xleft <- mean(x[lindx], na.rm = TRUE)
>          fit <- lm(y[x >= xleft] ~ x[x >= xleft])
>          panel.curve(coef(fit)[1] + (coef(fit)[2] * x),
>                      xleft, max(x, na.rm = TRUE))
>        })
>
> ---<---------------cut here---------------end---------------->---
>
> but can't find a way to color the line for each group differently.  I
> tried passing a length-2 vector as a 'col' argument to panel.curve.
> Unfortunately it's only picking the first, so that both lines get colored
> the same.  I'm not sure, but it seems as if I need to use
> 'panel.superpose' directly to do this, as the help page suggests the above
> would work?

The (somewhat mysterious) solution is the following:


xyplot(y ~ x | facA, groups = facB, data = toydf,
       panel = panel.superpose,
       panel.groups = function(x, y, col.line, ...) {
           panel.xyplot(x, y, ...)
           lindx <- which(y == max(y, na.rm = TRUE))
           xleft <- mean(x[lindx], na.rm = TRUE)
           fit <- lm(y[x >= xleft] ~ x[x >= xleft])
           panel.curve(coef(fit)[1] + (coef(fit)[2] * x),
                       col = col.line,
                       xleft, max(x, na.rm = TRUE))
       })

This uses the fact that panel.groups is always supplied a 'col.line'
argument (along with many others) which has been suitably calculated
for each group (see panel.superpose for how this works).

You are in fact using 'panel.superpose' directly, as that's what the
panel function defaults to when there is a 'groups' argument. However,
this will change in R-2.3.0, and to use a panel.groups argument, you
will need to explicitly specify panel=panel.superpose. Sorry for the
confusion, but I believe this to be more sensible in the bigger scheme
of things.

If you now want a different set of line colors, you can

(1) either modify the "superpose.line" parameter, or
(2) specify col.line = c('red', 'blue') etc in the xyplot call.

Hope that makes things a bit clearer.

Deepayan
--
http://www.stat.wisc.edu/~deepayan/




More information about the R-help mailing list