Stefan Stefan - 10 months ago 52
R Question

Sorting factors in multipanel plot in ggplot2 according to the first panel

Is it possible to sort factors in a multipanel plot in

ggplot2
according to the first panel? The first panel decides the order and the remaining panels follow that order.

Here is an example:

require(ggplot2)
set.seed(36)
xx<-data.frame(YEAR=rep(c("X","Y"), each=20),
CLONE=rep(c("A","B","C","D","E"), each=4, 2),
TREAT=rep(c("T1","T2","T3","C"), 10),
VALUE=sample(c(1:10), 40, replace=T))

ggplot(xx, aes(x=CLONE, y=VALUE, fill=YEAR)) +
geom_bar(stat="identity", position="dodge") +
facet_wrap(~TREAT)


Which gives me this plot:

enter image description here

Now I would like to sort
CLONE
based on the
VALUE
in
YEAR X
in a descending order (highest to lowest) but only for the Control (
C
panel). This order should then be maintained for
T1
,
T2
, and
T3
. By looking at the plot above, I want panel
C
sorted as
CLONE C
,
B
or
D
(both are 5),
A
and
E
. This order of
CLONE
should then be replicated for the remaining panels.

Answer Source

There's no easy way to do this right in ggplot since you have to reorder CLONE by 3 conditions, TREAT, YEAR and VALUE, otherwise forcats::fct_reorder2 could have been an option. Instead, extract the order of CLONE from the subset of data corresponding to YEAR = "X", TREAT = "C", and re-define your factor levels for the whole data set based on this subset.

library("ggplot2")
library("dplyr")
set.seed(36)

xx <- data.frame(YEAR = rep(c("X","Y"), each = 20),
           CLONE = rep(c("A","B","C","D","E"), each = 4, 2),
           TREAT = rep(c("T1","T2","T3","C"), 10),
           VALUE = sample(c(1:10), 40, replace = TRUE), stringsAsFactors = FALSE)

clone_order <- xx %>% subset(TREAT == "C"  & YEAR == "X") %>%
  arrange(-VALUE) %>% select(CLONE) %>% unlist()

xx <- xx %>% mutate(CLONE = factor(CLONE, levels = clone_order))

ggplot(xx, aes(x = CLONE, y = VALUE, fill = YEAR)) + 
  geom_bar(stat = "identity", position = "dodge") +
  facet_wrap(~TREAT)

giving

Barchart of CLONE ordered by a subpanel