[R] how to delete empty levels from lattice xyplot

P Ehlers ehlers at ucalgary.ca
Thu Mar 3 07:12:12 CET 2011


Dennis Murphy wrote:
> Hi:
> 
> On Wed, Mar 2, 2011 at 1:52 PM, John Smith <zmring at gmail.com> wrote:
> 
>> Hello All,
>>
>> I try to use the attached code to produce a cross over plot. There are 13
>> subjects, 7 of them in for/sal group, and 6 of them in sal/for group. But
>> in
>> xyplot, all the subjects are listed in both subgraphs. Could anyone help me
>> figure out how to get rid of the empty levels?
>>
> 
> Let's start with the data frame construction. Using the vectors from your
> original post,
> 
> studyLong <- data.frame(id = factor(rep(id, 2)),
>                          sequence = rep(sequence, 2),
>                          treat = c(treat1, treat2),
>                          pef = c(pef1, pef2))
> 
> Notice how I read the data frame from your original vectors. You made the
> mistake of mixing character with numeric vectors in forming a matrix - by
> doing that,
> the matrix type is coerced to character. You then coerced the matrix to a
> data frame,
> but because you didn't set stringsAsFactors = FALSE, all four of the
> variables
> in your data frame were factors. Something looked weird to me in your first
> graph, so I checked it with str():
>> str(studyLong)
> 'data.frame':   26 obs. of  4 variables:
>  $ id      : Factor w/ 13 levels "1","10","11",..: 1 9 11 12 2 3 6 7 8 10
> ...
>  $ sequence: Factor w/ 2 levels "for/sal","sal/for": 1 1 1 1 1 1 1 2 2 2 ...
>  $ treat   : Factor w/ 2 levels "for","sal": 1 1 1 1 1 1 1 2 2 2 ...
>  $ pef     : Factor w/ 20 levels " 90","210","220",..: 9 9 15 20 4 16 11 15
> 9 16 ...
> 
> After I re-read it per above, it looked like this:
>> str(studyLong)
> 'data.frame':   26 obs. of  4 variables:
>  $ id      : Factor w/ 13 levels  "1","2","3","4",..: 1 4 6 7 10 11 14 2 3 5
> ...
>  $ sequence: Factor w/ 2 levels "for/sal","sal/for": 1 1 1 1 1 1 1 2 2 2 ...
>  $ treat   : Factor w/ 2 levels "for","sal": 1 1 1 1 1 1 1 2 2 2 ...
>  $ pef     : num  310 310 370 410 250 380 330 370 310 380 ...
> 
> If I understand your question, you want the only the levels for each
> treatment group plotted in each panel. This is one way, but I'm guessing
> it's not quite what you were expecting ( I wasn't :):
> 
> xyplot(pef ~ id | sequence, groups=treat, data=studyLong,
>    auto.key=list(columns=2), scales = list(x = list(relation = 'free')))
> 
> I tried a couple of things without much success in lattice (I'm not
> terribly good at writing panel functions off the top of my head, I'm
> afraid),
> but it was pretty easy to get what I think you want from ggplot2:
> 
> library(ggplot2)
> g <- ggplot(studyLong, aes(x = id, y = pef, colour = treat))
> g + geom_point() + facet_wrap( ~ sequence, scales = 'free_x')
> 
> # or, using the simpler qplot() function,
> qplot(x = id, y = pef, colour = treat, data = studyLong, geom = 'point') +
>    facet_wrap( ~ sequence, scales = 'free_x')
> 
> If that's what you're after, one of the Lattice mavens can probably show
> you how to do it easily in Lattice as well. I'll probably learn something,
> too...

I'm no lattice expert, but it seems to me that here one
simple answer is to set the levels of 'id' appropriately:
just replace the line

  studyLong <- data.frame(id = factor(rep(id, 2)),

with

  studyLong <- data.frame(id = factor(rep(id, 2), levels=id),

and run the lattice code.

Peter Ehlers

> 
> For more on ggplot2: http://had.co.nz/ggplot2
> Scroll to the bottom to find the on-line help pages with examples.
> 
> HTH,
> Dennis
> 
> Thanks
>>
>>
>>
>> library(lattice)
>>
>> pef1 <- c(310,310,370,410,250,380,330,370,310,380,290,260,90)
>> pef2 <- c(270,260,300,390,210,350,365,385,400,410,320,340,220)
>> id <- c("1","4","6","7","10","11","14","2","3","5","9","12","13")
>> sequence <- c(rep('for/sal', 7), rep('sal/for', 6))
>> treat1 <- c(rep('for', 7), rep('sal', 6))
>> treat2 <- c(rep('sal', 7), rep('for', 6))
>> study <- data.frame(id, sequence, treat1, pef1, treat2, pef2)
>>
>> studyLong <- as.data.frame(rbind(as.matrix(study[,c('id', 'sequence',
>> 'treat1', 'pef1')]),
>>                                 as.matrix(study[,c('id', 'sequence',
>> 'treat2', 'pef2')])))
>> colnames(studyLong) <- c('id', 'sequence', 'treat', 'pef')
>>
>> xyplot(pef ~ id | sequence, groups=treat, data=studyLong,
>> auto.key=list(columns=2))
>>



More information about the R-help mailing list