## 15.8 Changing the Order of Factor Levels

### 15.8.1 Problem

You want to change the order of levels in a factor.

### 15.8.2 Solution

Pass the factor to `factor()`, and give it the levels in the order you want. This returns a new factor, so if you want to change the original variable, you’ll need to save the new result over it.

``````# By default, levels are ordered alphabetically
sizes <- factor(c("small", "large", "large", "small", "medium"))
sizes
#>  small  large  large  small  medium
#> Levels: large medium small

factor(sizes, levels = c("small", "medium", "large"))
#>  small  large  large  small  medium
#> Levels: small medium large``````

The order can also be specified with `levels` when the factor is first created:

``````factor(c("small", "large", "large", "small", "medium"),
levels = c("small", "medium", "large"))``````

### 15.8.3 Discussion

There are two kinds of factors in R: ordered factors and regular factors. (In practice, ordered levels are not commonly used.) In both types, the levels are arranged in some order; the difference is that the order is meaningful for an ordered factor, but it is arbitrary for a regular factor – it simply reflects how the data is stored. For plotting data, the distinction between ordered and regular factors is generally unimportant, and they can be treated the same.

The order of factor levels affects graphical output. When a factor variable is mapped to an aesthetic property in ggplot, the aesthetic adopts the ordering of the factor levels. If a factor is mapped to the x-axis, the ticks on the axis will be in the order of the factor levels, and if a factor is mapped to color, the items in the legend will be in the order of the factor levels.

To reverse the level order, you can use `rev(levels())`:

``factor(sizes, levels = rev(levels(sizes)))``

The tidyverse function for reordering factors is `fct_relevel()` from the forcats package. It has a syntax similar to the `factor()` function from base R.

``````# Change the order of levels
library(forcats)
fct_relevel(sizes, "small", "medium", "large")
#>  small  large  large  small  medium
#> Levels: small medium large``````