Re: [R] Auto.key colors maintained when subsetting

From: David Afshartous <dafshartous_at_med.miami.edu>
Date: Wed, 09 Jul 2008 15:13:53 -0400

On 7/9/08 1:07 PM, "Deepayan Sarkar" <deepayan.sarkar_at_gmail.com> wrote:

> On 7/9/08, David Afshartous <dafshartous@med.miami.edu> wrote:

>> 
>> 
>>  All,
>> 
>>  I'm plotting points and lines for various groups.
>>  I'd like subsequent plots done on subsets to maintain the color assignments
>>  from the original plot.  This works fine, but the key for the subset doesn't
>>  maintain the correspondence.  One solution is to reprint the entire key, but
>>  this is undesirable since then the key has more elements than the groups in
>>  the plot.  Reproducible example below.

>
> Well, the ideal solution would have been for auto.key to magically
> omit the levels of 'groups' that are omitted by the application of
> 'subset', but there is not enough information available to it for this
> to happen. One option is to
>
> 1. subset the data beforehand, and drop unsed levels with Group[drop=TRUE]
>

This will work, but unfortunately the color correspondence across plots will be lost. Leading to a preference for your second suggestion:

> 2. supply colors, etc. explicitly through 'par.settings'.
>

The code below works, but when extended to include error bars (panel.ci, and prepanel.ci), it works for the full data but not the subset.

## full data w/ colors supplied, this works: xyplot(Y ~ Hour,

        data = dat, pch = 16,
        groups=Group, col=c('red', 'black', 'green', 'blue'),
        type="b",
        auto.key = list(space = "top",  text = levels(Group),
         points = FALSE, lines = TRUE, columns=4),
        par.settings = list(superpose.line = list(lty = c(1,2,3,4),
         col=c('red', 'black', 'green', 'blue')
) ) )

## subset of data; this works:
dev.new() xyplot(Y ~ Hour,

        data = dat, pch = 16,
        subset = (Group != "A"),
        groups=Group, col=c('red', 'black', 'green', 'blue'),
         lty = c(1,2,3,4),
        type="b",
        auto.key = list(space = "top",  text = levels(Group)[2:4],
         points = FALSE, lines = TRUE, columns=3),
        par.settings = list(superpose.line = list(lty = c(2,3,4),
         col=c('black', 'green', 'blue')
) ) )

## full data w/ error bars, this works:
xyplot(Y ~ Hour,

        data = dat, pch = 16,
        groups=Group, col=c('red', 'black', 'green', 'blue'),
         lty = c(1,2,3,4),
        ly = dat$lower.bound ,
        uy = dat$upper.bound ,
        prepanel = prepanel.ci,
        panel = panel.superpose,
        panel.groups = panel.ci,
        type="b",
        auto.key = list(space = "top",  text = levels(Group),
         points = FALSE, lines = TRUE, columns=4),
        par.settings = list(superpose.line = list(lty = c(1,2,3,4),
         col=c('red','black', 'green', 'blue')
) ) )

## subset of data w/ error bars produces error message: Error using packet ## 1, Invalid Line Type:

xyplot(Y ~ Hour,

        data = dat, pch = 16,
        subset = (Group != "A"),
        groups=Group, col=c('red', 'black', 'green', 'blue'),
         lty = c(1,2,3,4),
        ly = dat$lower.bound ,
        uy = dat$upper.bound ,
        prepanel = prepanel.ci,
        panel = panel.superpose,
        panel.groups = panel.ci,
        type="b",
        auto.key = list(space = "top",  text = levels(Group)[2:4],
         points = FALSE, lines = TRUE, columns=3),
        par.settings = list(superpose.line = list(lty = c(2,3,4),
         col=c('black', 'green', 'blue')
) ) )

> The other option is to construct your own key (i.e., use the 'key'
> argument, not 'auto.key', to specify the legend).

Below is an attempt to use key; although the plot is correct, in the key the color is applied to the text instead of the line and the line type isn't drawn:

xyplot(Y ~ Hour,

        data = dat, pch = 16,
        subset = (Group != "A"),
        groups=Group, col=c('red', 'black', 'green', 'blue'),
        type="b",
        key = simpleKey(text = levels(Group)[2:4], lty = c(2,3,4),
             space = "top", columns = 3, points = FALSE, lines = TRUE,
             col = c('black', 'green', 'blue'))
        par.settings = list(superpose.line = list(lty = c(1,2,3,4),
         col=c('red', 'black', 'green', 'blue')
) ) )
#############################

Data and necessary functions:
set.seed(101)
Y = c(rnorm(4,0), rnorm(4,2), rnorm(4,6), rnorm(4,8)) dat = data.frame(

    Y , lower.bound = Y - .5, upper.bound = Y + .5,     Group = factor(c(rep("A", 4), rep("B", 4), rep("C", 4), rep("D", 4))),     

Hour = rep(c(1:4), 4)
)
prepanel.ci <- function(x, y, ly, uy, subscripts, ...) {

    x <- as.numeric(x)
    ly <- as.numeric(ly[subscripts])
    uy <- as.numeric(uy[subscripts])
    list(ylim = range(y, uy, ly, finite = TRUE)) } panel.ci <- function(x, y, ly, uy, subscripts, pch = 16, ...) {

    x <- as.numeric(x)
    y <- as.numeric(y)
    ly <- as.numeric(ly[subscripts])
    uy <- as.numeric(uy[subscripts])
    panel.arrows(x, ly, x, uy, col = "black",

                 length = 0.25, unit = "native",
                 angle = 90, code = 3)

    panel.xyplot(x, y, pch = 16, ...)}

> It should be simple
> to write a function that constructs a suitable 'key' argument given
> the levels that are to be omitted/retained.
>
> -Deepayan



R-help_at_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. Received on Wed 09 Jul 2008 - 20:05:02 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 Wed 09 Jul 2008 - 22:31:21 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.

list of date sections of archive