1

I am attempting to plot a single column of data (len) that has three groups (mea, tre, and sex) across six boxplots in a single graph. The data is broken up into the "mea" group first, then subdivided further by "tre," and finally by "sex."

There are plenty of similar questions on StackOverflow (see Plot multiple boxplot in one graph or How to display two groups of boxplots?, but I cannot seem to replicate any of their solutions on my data set.

Probably the closest I've come is using:

dataSummary <- summarySE(my.df, measurevar="len", groupvars=c("sex", "tre", "mea"))
ggplot(dataSummary, aes(x=mea, y=len, fill=sex)) +
+ geom_bar(position=position_dodge(), stat="identity") +
+ geom_errorbar(aes(ymin=len-se, ymax=len+se), width = .2, position=position_dodge(.9))

...but that doesn't give anywhere near the right output (an entire group seems to be missing).

Can anyone provide a solution to fill in what I'm missing?

The dput of my data frame:

structure(list(mea = structure(c(1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L), .Label = c("phe", "mel"), class = "factor"), 
    tre = structure(c(1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 3L, 3L, 
    1L, 1L, 1L, 1L, 3L, 2L, 2L, 1L, 3L, 2L, 2L, 2L, 2L, 1L, 2L, 
    2L, 2L, 2L, 1L, 3L, 2L, 1L, 3L, 1L, 1L, 2L, 3L, 2L, 3L, 1L, 
    2L, 1L, 1L, 3L, 3L, 2L, 3L, 2L, 3L, 3L, 1L, 2L, 3L, 3L, 1L, 
    2L, 2L, 2L, 3L, 2L, 1L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 2L, 3L, 
    3L, 3L, 3L), .Label = c("a", "b", "c"), class = "factor"), 
    sex = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    2L, 2L, 1L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 
    1L, 2L, 2L, 2L, 2L, 1L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 
    1L, 1L, 2L, 1L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 2L, 1L, 1L, 
    2L, 1L, 1L, 2L, 2L, 1L, 2L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 
    1L), .Label = c("m", "f"), class = "factor"), len = c(10.1, 
    10, 9.4, 11.1, 10.4, 10, 10.4, 11, 9.5, 10, 9.4, 9.2, 10.9, 
    11.6, 12.2, 10.3, 11, 11.4, 10.5, 10.9, 11, 11, 12, 10.7, 
    10.1, 11, 10.5, 10.8, 9.9, 11.4, 10, 11.9, 10, 12.2, 12.1, 
    11.8, 10.8, 10.4, 10.9, 11.7, 10, 10.6, 10.4, 10.9, 11, 9, 
    9.1, 9.8, 10, 9.9, 10.6, 11.5, 10.4, 10.7, 10.3, 10.6, 10, 
    11.6, 10.6, 10.7, 10.8, 10.1, 11.4, 10.2, 11.9, 10.2, 11, 
    9.5, 10.3, 10.8, 10.7, 11.5, 10.7, 9.4, 10, 11.7, 9.9, 10.7, 
    10, 9.8, 9.2, 10.9, 10.8, 10.6, 8.5, 11.2, 10.9, 10.8, 10.3, 
    10.2, 11, 10.4, 10.3, 10, 9, 10.5, 10.3, 9.5, 10.9, 11.5, 
    10.5, 9.5, 10, 10, 11.2, 10.1, 8.8, 10.6, 10, 11.1, 10.9, 
    10.5, 11.5, 10.5, 10.9, 11.6, 9.8, 10.8, 8.9, 10, 11, 11.8, 
    11, 11.1, 10.7, 12.1, 10.4, 11.8, 10.5, 8.9, 9.6, 8.7, 10.7, 
    8.8, 11.7, 9.8, 10.7, 10.6, 10.1, 11.3, 11.6, 11.2, 8.8, 
    11.2, 9.8, 10.7, 9.1, 10.1, 10.7, 10.1, 11.3, 9.9, 9.9, 10.1, 
    11.2, 11.1, 12, 11.9, 10.8, 12.1, 12, 13.1, 10.5, 12, 12.5, 
    12.2, 12, 11.5, 11.1, 10.9, 11.5, 10.5, 12, 13, 11.1, 10.5, 
    12, 11, 11.5, 13, 13, 11.3, 12, 11.5, 9.1, 13, 11.2, 10.5, 
    11.9, 12.5, 12, 9, 13, 11, 11.3, 10.5, 11.5, 12.1, 12, 11, 
    11.8, 11.4, 10.5, 13, 12.5, 12.2, 11.9, 11.4, 11, 11.9, 12, 
    11.5, 11.9, 10.8, 13, 11.8, 12.9, 12.4, 11.6, 11, 10.3, 13, 
    10.2, 10.8, 12.7, 11.2, 11.2, 11.1, 11.3, 12.1, 11.9, 13, 
    11.9)), .Names = c("mea", "tre", "sex", "len"), row.names = c(NA, 
-233L), class = "data.frame")
Community
  • 1
  • 1
rls
  • 57
  • 6

2 Answers2

1

What if you use fill=interaction(sex, tre) in the ggplot call? I'm not exactly sure what output you want.

Chris Watson
  • 1,347
  • 1
  • 9
  • 24
  • Chris, thanks for the suggestion. I'm looking for a plot closer to what Robert posted above. If I could figure out how to do something similar in ggplot, that would be great, as it seems to have more options for fine-tuning what I want. Does that help in regards to what I'm looking for? The output from your suggestion is close, but I'd like the "tre" and "sex" groups to be together (that is, a.m next to a.f, then a small gap, then b.m next to b.f, and so on). Does that help clarify at all? – rls Jun 30 '15 at 16:59
  • Then what about `ggplot(my.df, aes(x=tre, y=len, col=interaction(sex, mea))) + geom_boxplot()` – Chris Watson Jun 30 '15 at 18:33
  • Or perhaps this is closer: `ggplot(my.df, aes(x=mea, y=len, col=sex)) + geom_boxplot() + facet_wrap(~ tre)` – Chris Watson Jun 30 '15 at 18:37
  • Great. That worked perfectly. As a side question, is there any way to replicate this, but using points with standard error instead of a box plot? The closest I can get is something like `sum <- summarySE(my.df, measurevar="len", groupvars=c("mea", "tre", "sex")) limits <- aes(ymax = len + elSum$se, ymin = len - elSum$se) ggplot(my.df, aes(x=mea, y=len, color=sex)) + geom_point() + geom_errorbar(limits, width=0.2) + facet_wrap(~ sex + tre)` but I'd like it to be in the output style of `ggplot(my.df, aes(x=mea, y=len, col=sex)) + geom_boxplot() + facet_wrap(~ tre)`? – rls Jun 30 '15 at 23:34
1

One way would be:

my.df$gr<-apply(my.df[,c("mea","tre","sex")],1,paste,collapse=".")
boxplot(my.df$len~my.df$gr,las=2,col=rainbow(length(unique(my.df$gr))))

enter image description here

You could of course personalize colors and distances. For example:

boxplot(my.df$len~my.df$gr,las=2,col=c("darkgray","lightgray"),
        boxwex = 0.7, at = c(0.8,1.8,3,4,5.2, 6.2,7.4,8.4,9.6, 10.6, 11.8,12.8))

enter image description here

Robert
  • 5,038
  • 1
  • 25
  • 43
  • Thanks Robert, this is pretty close to what I'd like. Can you explain what your first data frame using 'apply' is doing? I'm not familiar with that operation. Also, how would I add a bit of space between each group (ie, between mel.a and mel.b)? Lastly, is there any way to color the sexes similarly (ie, all males dark gray while all females light gray)? – rls Jun 30 '15 at 16:52
  • apply computes (applies) a function, in this case paste, to every row (1) or column (2) of a matrix object. See ?apply. For other questions see the edit. – Robert Jun 30 '15 at 20:51