Is there a standard way to facet some data in one direction, but other data in two directions in ggplot2?

Viewed 85

An example of when this might be useful is where there is an experiment with two treatments and a control group, with both male and female participants. You might want to facet the treatment data across both treatment and sex, but replicate the control data across the treatment facets and only change what is displayed based on sex. I have found two different ways to do this but I am wondering if there is a way besides these ways that might be considered more standard.

Example data:

library(tidyverse)
experiment <- tibble(X = c(-19:20,-19:20,-19:20), 
                     Y = c((-19:20)^3,
                          ((-19:20)^4)/40,
                           abs(-19:20)*100)*rep(c(-1,1), times = 60), 
                     sex = rep(c("Male","Female"), times = 60),
                     treatment = c(rep("a",times = 40),
                                   rep("b", times = 40),
                                   rep("control", times = 40)))

This is the basic faceting which I don't prefer:

ggplot(experiment, aes(x = X, y = Y, color = treatment)) + 
  facet_grid(rows = vars(sex), cols = vars(treatment)) + 
  geom_point() +
  scale_color_manual(values = c(control = "black", a = "red", b = "blue"))

enter image description here

One way to fix it is to separate the control data and remove the "treatment" column and add it as a separate layer to the plot:

treated <- experiment %>% filter(treatment != "control")
control <- experiment %>% filter(treatment == "control") %>% select(-treatment)

ggplot(treated, aes(x = X, y = Y)) + 
  facet_grid(rows = vars(sex), cols = vars(treatment)) +
  geom_point(aes(color = treatment)) + 
#note the new data argument to geom_point
  geom_point(data = control, mapping = aes(  x = X, y = Y, color = "control")) +
  scale_color_manual(values = c(control = "black", a = "red", b = "blue"))

enter image description here

With no treatment variable, the control data is only faceted across sex, and is identical across treatment, which is what I want.

Another approach is to make a new variable for faceting, with the treated data having that variable identical to the variable for coloring, and duplicating the control data, changing the faceting variable so that the control data facets the way we want:

control <- experiment %>% filter(treatment == "control") 
control_a <- control %>% mutate(treatment_alt = "a")
control_b <- control %>% mutate(treatment_alt = "b")
treated <- treated %>% mutate(treatment_alt = treatment)

experiment_doubled <- bind_rows(control_a,control_b, treated)

ggplot(experiment_doubled, aes(x = X, y = Y, color = treatment)) + 
  geom_point() + 
  facet_grid(rows = vars(sex), cols = vars(treatment_alt)) +
  scale_color_manual(values = c(control = "black", a = "red", b = "blue"))

This is less ideal because the duplicated data makes using the dataframe potentially more complicated for modelling with.

So, I have these two approaches, but I'm wondering if there is another way that is accepted as more standard across the Tidyverse community, or if what I'm doing already is the best solution? If so, which is the better of the two methods I've presented?

0 Answers
Related