48

I plotted a facet plot using ggplot and here is the plot

https://i.stack.imgur.com/5qXF1.png

The problem I have is, The facets(labels) are sorted alphabetically (Ex: E1, E10, E11,E13, E2, E3, I1, I10, I2) but I need them to be a custom order like E1, I1, E2, I2, E3, E10, I10, E11, E13.

How can I do that ?

NelsonGon
  • 13,015
  • 7
  • 27
  • 57
Jana
  • 659
  • 2
  • 7
  • 9
  • 7
    Rearrange the order of the underlying factor. You can use `relevel()` or `reorder()` or make a custom order and use `factor()`. – Chase Mar 30 '11 at 18:53
  • Does this answer your question? [Fixing the order of facets in ggplot](https://stackoverflow.com/questions/14262497/fixing-the-order-of-facets-in-ggplot) – jan-glx Jul 16 '20 at 15:56

2 Answers2

57

Don't rely on the default ordering of levels imposed by factor() or internally by ggplot if the grouping variable you supply is not a factor. Set the levels explicitly yourself.

dat <- data.frame(x = runif(100), y = runif(100), 
                  Group = gl(5, 20, labels = LETTERS[1:5]))
head(dat)
with(dat, levels(Group))

What if I want them in this arbitrary order?

set.seed(1)
with(dat, sample(levels(Group)))

To do this, set the levels the way you want them.

set.seed(1) # reset the seed so I get the random order form above
dat <- within(dat, Group <- factor(Group, levels = sample(levels(Group))))
with(dat, levels(Group))

Now we can use this to have the panels drawn in the order we want:

require(ggplot2)
p <- ggplot(dat, aes(x = x)) + geom_bar()
p + facet_wrap( ~ Group)

Which produces:

facets wrapped

smci
  • 32,567
  • 20
  • 113
  • 146
Gavin Simpson
  • 170,508
  • 25
  • 396
  • 453
  • Same as above but if the data itself is already in the custom order you want the `Group` variable to be in and you don't want to manually create a vector in that order: `dat <- within(dat, Group <- factor(Group, levels = unique(levels(Group))))` since `unique` preserves the order – CrunchyTopping Jun 03 '20 at 18:45
  • Good answer, solved my problem but felt I should add a comment in case any others come across the issue I was having: If you have two data sources being called at different times (e.g. in the initial ggplot() and a different data in geom_line()), then both data sources must have the faceting variable factored and ordered in the same way for them to plot in the desired order. – KSkoczek Nov 07 '22 at 12:01
2

Just being working on a similar problem. I have levels which look like this by default:

 [1] "A1"  "A10" "A2"  "A3"  "A4"  "A5"  "A6"  "A7"  "A8"  "A9" 
[11] "B1"  "B2"  "B3"  "B4"  "B5"  "B6"  "B7"  "B8"  "B9" 

Note that the second level is out of place due to alphabetical order.

This is what I am doing to fix the order:

reorder(factor(fct),
        fct %>%
          str_replace("([[:alpha:]]+)", "\\1|") %>%
          str_split("\\|") %>%
          sapply(function(d) sprintf("%s%02d", d[1], as.integer(d[2]))),
        function(x) x[1])

It replaces levels like "A1" with "A01" then reorders according to these. I'm sure that you could do this a lot more efficiently, but it does the job.

It could be adapted to address the original problem.

datawookie
  • 1,607
  • 12
  • 20