Skip to content

plot separate groups with plotmeans()

2 messages · Jon Zadra, Dennis Murphy

#
Hi,

I often use plotmeans() from the gplots package to quickly visualize a 
pattern of change.  I would like to be able to plot separate lines for 
different groups, but the function gives an error when a grouping 
variable is included in the formula argument.

For instance,
 > require(gplots)
 > x <- data.frame(Score=rnorm(100), Time=rep(1:10, 10), 
Group=factor(rep(c("A","B"),50)))
 > plotmeans(Score ~ Time, x) #works fine
 > plotmeans(Score ~ Time * Group, x)
Error in .subset2(x, i, exact = exact) :
   attempt to select more than one element
 > plotmeans(Score ~ Time | Group, x)
Error in ns - 1 : non-numeric argument to binary operator
In addition: Warning message:
In Ops.factor(Time, Group) : | not meaningful for factors

The help for plotmeans() states that it accepts a formula object 
including a grouping variable.  There is no other grouping argument 
listed.  Any help is appreciated, including pointing to a more robust 
function for plotting means.

Thanks,

Jon
#
Hi:

Here are a couple of ways using the plyr and ggplot2 packages:

library('plyr')
library('ggplot2')

# Create a summary data frame that computes the mean
# and standard deviation at each time/group combination
xsumm <- ddply(x, .(Time, Group), summarise, m = mean(Score), s = sd(Score))

# Create a new time variable to appose the two groups at
# each time (in case that was the intent):
xsumm2 <- mutate(xsumm, Time2 = rep(1:5, each = 2))

# Plot 1: Plot all 10 times in one panel, using color to
#            separate the two groups
ggplot(xsumm, aes(x = Time, y = m)) +
   geom_errorbar(aes(ymin = m - s, ymax = m + s, colour = Group),
                         size = 1) +
   geom_point(size = 3, colour = 'red') +
   geom_line(aes(group = 1),  colour = 'red', size = 1) +
   scale_colour_manual(breaks = c('A', 'B'),
                         values = c('blue', 'orange')) +
   scale_x_continuous(breaks = 1L:10L) +
   ylab('Score')

# Plot 2: Separate the two groups into different panels
ggplot(xsumm2, aes(x = Time2, y = m)) +
   geom_errorbar(aes(ymin = m - s, ymax = m + s),
                 colour = 'blue', size = 1, width = 0.4) +
   geom_point(size = 3, colour = 'red') +
   geom_line(aes(group = 1), colour = 'red', size = 1) +
   labs(x = 'Time', y = 'Score') +
   facet_wrap(~ Group, ncol = 1)

# Plot 3: Put the groups side by side at each time
# This one is a little trickier...
ggplot(xsumm2, aes(x = Time2, y = m)) +
   geom_errorbar(aes(ymin = m - s, ymax = m + s, colour = Group),
                 position = position_dodge(width = 0.4),
                 size = 1, width = 0.4) +
   geom_point(size = 3, colour = 'red',
              position = position_dodge(width = 0.4)) +
   geom_line(aes(group = Group), colour = 'red', size  = 1,
              position = position_dodge(width = 0.4)) +
   labs(x = 'Time', y = 'Score') +
   scale_colour_manual(breaks = c('A', 'B'),
                         values = c('blue', 'orange'))

You might have to be careful about saving the last plot, especially if
you want to shrink the size or change the aspect ratio - it might
upset the alignment of the bars, lines and points. If you save it at
the standard size (7'' x 7'') you should be fine. See the ggsave()
function in the ggplot2 package for details (?ggplot2::ggsave once the
package is installed).

If this is new to you, go to http://had.co.nz/ggplot2/ for the
package's web page; the on-line help files (with many examples) start
as you scroll toward the bottom of the page. Click on the book's
website (linked from the above site) to access the chapter on qplots,
the entry level chapter of the ggplot2 book.

This would be harder to do in the lattice package because it doesn't
have a built-in error bar panel function (by design, I think :).

HTH,
Dennis
On Tue, Nov 8, 2011 at 4:19 PM, Jon Zadra <jrz9f at virginia.edu> wrote: