3

I want to create multiple facets of boxplots of my data, which illustrate the amount of each of the chemicals present under various conditions.

I have two categorical variables, M1 and M2, which take the values "small, medium, large" and "low, medium, high" respectively. I want these to form the basis of a 3x3 facet grid.

I then have 8 chemicals A-H which take a numeric value, and I want a boxplot for each chemical on each facet.

I've made a 3x3 facet grid, but only with one chemical on each.

EDIT (data taken from answer) my data looks like the data generated from:

set.seed(1234)

n <- 100
M1 <- sample( c("small", "medium", "large"), n, TRUE)
M2 <- sample( c("low", "medium", "high"), n, TRUE)
tmp <- matrix(sample(100, 8*n, TRUE), ncol = 8)
colnames(tmp) <- LETTERS[1:8]

df <- data.frame(M1, M2)
df <- cbind(df, tmp)
rm(M1, M2, tmp)

My code for my plot:

df %>%
  ggplot(aes(x = M1, y = A, fill = M1)) +
  geom_boxplot() +
  theme_minimal() +
  facet_grid(M2 ~ M1)

I think I need to reshape my data, so that y = 'measure' before I do the faceted boxplots but I'm not sure how

I want a 3x3 grid of facets, such that the bottom left would correspond to "small","low", and top right would be "large","high", with 8 box plots on each facet for each of the chemicals A-H.

I want for each facet the y-axis is a numerical measure, the x-axis is discrete label A-H (for the 8 boxplots). For the overall 3x3 grid, the (top) x-axis would be 3 labels, small, medium, large, and the (right) y-axis would be 3 labels, low, medium, high?

Laura
  • 177
  • 1
  • 12
  • Could you make your problem reproducible by sharing a sample of your data so others can help (please do not use `str()`, `head()` or screenshot)? You can use the [`reprex`](https://reprex.tidyverse.org/articles/articles/magic-reprex.html) and [`datapasta`](https://cran.r-project.org/web/packages/datapasta/vignettes/how-to-datapasta.html) packages to assist you with that. See also [Help me Help you](https://speakerdeck.com/jennybc/reprex-help-me-help-you?slide=5) & [How to make a great R reproducible example?](https://stackoverflow.com/q/5963269) – Tung Dec 29 '18 at 17:59
  • I've added some code (from Rui) into my question which produces an example of my data. – Laura Dec 29 '18 at 19:31

1 Answers1

2

Reshape the data with package reshape2, function melt. Then use interaction to define the box groups.

long <- reshape2::melt(df, id.vars = c("M1", "M2"))

ggplot(long, aes(x = M1, y = value, group = interaction(M1, M2), fill = M2)) +
  geom_boxplot() +
  theme(axis.text.x = element_text(angle = 30, hjust = 1)) +
  facet_wrap( ~ variable, scales = "free")

enter image description here

To answer the request in the comment, see if this is what you mean.

ggplot(long, aes(x = variable, y = value, group = interaction(M1, variable), fill = M2)) +
  geom_boxplot() +
  facet_grid(M1 ~ M2, scales = "free")

enter image description here

Test data creation code.

I have coerced M2 to factor in order to have the legend properly ordered.

set.seed(1234)

n <- 100
M1 <- sample( c("small", "medium", "large"), n, TRUE)
M2 <- sample( c("low", "medium", "high"), n, TRUE)
M2 <- factor(M2, levels = c("low", "medium", "high"))
tmp <- matrix(sample(100, 8*n, TRUE), ncol = 8)
colnames(tmp) <- LETTERS[1:8]

df <- data.frame(M1, M2)
df <- cbind(df, tmp)
rm(M1, M2, tmp)
Rui Barradas
  • 70,273
  • 8
  • 34
  • 66
  • This is much closer to what I want! How would you code the interaction to produce a 3x3 grid of facets, such that the bottom left would correspond to "small","low", and top right would be "large","high", with 8 box plots on each facet for each of the chemicals A-H? For each facet the y-axis is a numerical measure, the x-axis is discrete label A-H (for the 8 boxplots). For the overall 3x3 grid, the (top) x-axis would be 3 labels, small, medium, large, and the (right) y-axis would be 3 labels, low, medium, high? – Laura Dec 29 '18 at 19:36
  • @Laura Done, see if this is it. And note that I have changed the data creation code. – Rui Barradas Dec 29 '18 at 19:56
  • Fantastic thank you! Is there a way to change the order of M1 and M2? currently my boxplots are ordered from left to right "high medium low" and from bottom to top "medium small large" – Laura Dec 30 '18 at 13:22
  • @Laura That depends on the order of the factors `M1` and `M2`. In the data creation code see the line where `M2` is coerced to factor. The `levels` argument determines the order of the plots. – Rui Barradas Dec 30 '18 at 14:28
  • I am using data that has been provided, I have tried `fct_relevel(levels(factor(long$M1)),c("small","medium","large"))` but it doesn't work, neither does `levels(factor(long$M1) <- fct_relevel(levels(factor(long$M1)),c("small","medium","large"))`. Do you have a suggestion? – Laura Dec 30 '18 at 15:17
  • @Laura Try `long$M1 <- factor(as.character(long$M1), levels = c("small","medium","large"))`. – Rui Barradas Dec 30 '18 at 16:30
  • Perfect! Thank you. – Laura Dec 30 '18 at 16:46
  • I've made 4 of these facet grids (from four different datasets, one for each season), I'm working in an R markdown file, each of these 4 facet grids are shown individually. Is there a way to get these to display in a line all at once, or in a 2x2 grid? – Laura Dec 30 '18 at 17:33