# [R] plot separate groups with plotmeans()

Dennis Murphy djmuser at gmail.com
Wed Nov 9 02:34:50 CET 2011

```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:
> 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 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
> --
> Department of Psychology
> University of Virginia
> P.O. Box 400400
> Charlottesville VA 22904
> (434) 982-4744