简体   繁体   中英

Group-specified geom_boxplot from summary statistics fails to generate boxplots in r

I am trying to make a box plot from summary statistics generated from simulation data--I am not plotting raw data. The summary data look like this:

require(tidyverse)

df <- tibble(Source = c("A","A","B","B","C","C"),
             Group = c("y","n","y","n","y","n"),
             y2.5 = c(0.592,0.471,0.182,0.285,0.024,0.031),
             y25 = c(0.633,0.53,0.217,0.325,0.059,0.081),
             y50 = c(0.673,0.547,0.24,0.347,0.08,0.106),
             y75 = c(0.699,0.58,0.267,0.370,0.103,0.130),
             y97.5 = c(0.764,0.61,0.312,0.414,0.146,0.173))

I want to generate box plots for each Source along the x-axis, paired by Group . As you can see, there is one set of summary values for each combination of group and source.

I see from the vignettes that geom_boxplot(aes()) accepts summary values plotted this way:

ggplot(df, aes(Source, group = Group))+
  geom_boxplot(aes(ymin = y2.5, lower = y25, middle = y50, upper = y75, ymax = y97.5),
               stat = "identity")

But this code run on these data generates this error:

Error: Can't draw more than one boxplot per group. Did you forget aes(group = ...)?

I have moved the group argument into the box plot aes() call but this produces the same error message. This feels a lot like a simple problem caused by some late-night oversight but I just can't see it... maybe I have been staring too long. Any help with this would be much appreciated.

I don't think you can map to "group" (more details: https://ggplot2.tidyverse.org/reference/aes_group_order.html ), as far as I know you need to map to an aesthetic like "color", "fill", "alpha", "shape", "size", and/or "linetype" to get the outcome you want, eg

library(tidyverse)

df <- tibble(Source = c("A","A","B","B","C","C"),
             Group = c("y","n","y","n","y","n"),
             y2.5 = c(0.592,0.471,0.182,0.285,0.024,0.031),
             y25 = c(0.633,0.53,0.217,0.325,0.059,0.081),
             y50 = c(0.673,0.547,0.24,0.347,0.08,0.106),
             y75 = c(0.699,0.58,0.267,0.370,0.103,0.130),
             y97.5 = c(0.764,0.61,0.312,0.414,0.146,0.173))

ggplot(df, aes(x = Source, fill = Group)) +
  geom_boxplot(aes(ymin = y2.5, lower = y25,
                   middle = y50, upper = y75,
                   ymax = y97.5),
               stat = "identity")

ggplot(df, aes(x = Source, color = Group)) +
  geom_boxplot(aes(ymin = y2.5, lower = y25,
                   middle = y50, upper = y75,
                   ymax = y97.5),
               stat = "identity")

Or, another potential alternative is to plot the interaction between Group and Source, eg

ggplot(df, aes(x = interaction(Group, Source))) +
  geom_boxplot(aes(ymin = y2.5, lower = y25,
                   middle = y50, upper = y75,
                   ymax = y97.5),
               stat = "identity")

Created on 2021-07-12 by the reprex package (v2.0.0)

Each group label needs to be distinct. You can use an interaction with source to force that

  ggplot(df, aes(Source))+
  geom_boxplot(aes(ymin = y2.5, lower = y25, middle = y50, upper = y75, ymax = y97.5, 
                   group = interaction(Source, Group)),
               stat = "identity")

But using fill as suggested by jared_mamrot is probably a better solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM