Reordering groups in a ggplot2 graphic is sometimes seen as a struggle. This is due to the fact that ggplot2 takes into account the order of the factor levels, not the order you observe in your data frame. You can sort your input data frame with sort() or arrange(), it will never have any impact on your ggplot2 graphic.

This post explains how to reorder the level of your factor through several examples. To go further, I strongly advise to read the dedicated chapter of the book R for data science. Examples are based on 2 dummy datasets:




The Forecats library

The Forecast library is a library from the tidyverse specially made to handle factors in R. It provides a suite of useful tools that solve common problems with factors. The fact_reorder function allows to reorder the factor (data$name for example) following the value of another column (data$val here).


If you have several values per level of your factor, you can specify which function to apply to determine the order. The default is to use the median, but you can use the number of data points per group to make the classification:






The last common operation is to provide a specific order to your levels, you can do so using the fct_relevel function:





Using dplyr only

The mutate function of dplyr allows to create a new variable or modify an existing one. It is possible to use it to recreate a factor with a specific order. Here are 2 examples:

  • The first use arrange() to sort your data frame, and reorder the factor following this desired order.
  • The second specify a custom order for the factor giving the levels one by one.



Using base R: the reorder function




In case your an unconditional user of the good old R, here is how to control the order using the reorder function:







Not what you are looking for ? Make a new search !

Leave a Reply

1 Comment threads
0 Thread replies
Most reacted comment
Hottest comment thread
1 Comment authors
Anonymous Recent comment authors
newest oldest most voted
Notify of

I struggled with ordering boxplots for a whole afternoon. In the end, I figured out that I had some missing data, and that the fun argument needed na.rm=TRUE.

“mutate(class = fct_reorder(class, hwy, fun=median,na.rm=TRUE)) %>%”