forcats::fct_relevel

Lisa Rogash

In this document, I will introduce the fct_relevel function and show what it’s for.

#load tidyverse up
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.0.3
## -- Attaching packages --------------------------------------- tidyverse 1.3.0 --
## v ggplot2 3.3.3     v purrr   0.3.4
## v tibble  3.0.6     v dplyr   1.0.4
## v tidyr   1.1.2     v stringr 1.4.0
## v readr   1.4.0     v forcats 0.5.1
## Warning: package 'ggplot2' was built under R version 4.0.3
## Warning: package 'tibble' was built under R version 4.0.3
## Warning: package 'tidyr' was built under R version 4.0.3
## Warning: package 'readr' was built under R version 4.0.3
## Warning: package 'purrr' was built under R version 4.0.3
## Warning: package 'dplyr' was built under R version 4.0.3
## Warning: package 'stringr' was built under R version 4.0.3
## Warning: package 'forcats' was built under R version 4.0.3
## -- Conflicts ------------------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()
#dataset
data(diamonds)

What is it for?

fct_relevel allows you to move any number of levels to any location. To demonstrate this function, I am using the tidyverse’s built-in dataset, diamonds.

Factor levels can be ordered or unordered. In the diamonds dataset, “cut” is an ordered factor vector. We often use factor vectors to aid in data visualization. In the boxplot below, we are comparing the depths of diamonds by cut. R automatically sorts the boxplots from “Fair” to “Ideal”.

levels(diamonds$cut)
## [1] "Fair"      "Good"      "Very Good" "Premium"   "Ideal"
diamonds %>%
 ggplot(aes(x=cut,y=depth,fill=cut)) +
  geom_boxplot()

What if your factor levels aren’t in the correct order?

diamonds <- diamonds %>% 
  mutate(cut = fct_shuffle(cut))
levels(diamonds$cut)
## [1] "Ideal"     "Very Good" "Good"      "Premium"   "Fair"
diamonds %>%
 ggplot(aes(x=cut,y=depth,fill=cut)) +
  geom_boxplot()

We can use fct_relevel() to fix this! If you want to move a single value to the beginning of the levels vector, you can use the fct_relevel() function with only the factor vector and the value you wish to move as the arguments.

diamonds <- diamonds %>% 
  mutate(cut = fct_relevel(cut, "Fair"))
levels(diamonds$cut)
## [1] "Fair"      "Ideal"     "Very Good" "Good"      "Premium"

If you want to move a value to a different spot, you add in the argument “after” which you set to the integer value of the spot you want the value to be after. If you want the value at the end, but you don’t know how many levels there are, you can use after=Inf (don’t forget the capital ‘I’!).

diamonds <- diamonds %>% 
  mutate(cut = fct_relevel(cut, "Good", after=1))
levels(diamonds$cut)
## [1] "Fair"      "Good"      "Ideal"     "Very Good" "Premium"

If you want to move multiple values, you can set your second argument to a vector of the elements you want to move.

diamonds <- diamonds %>% 
  mutate(cut = fct_relevel(cut, c("Very Good","Premium"), after=2))
levels(diamonds$cut)
## [1] "Fair"      "Good"      "Very Good" "Premium"   "Ideal"

You can also use functions in fct_relevel.

#sorts to alphabetical order or numerical order
diamondssort <- diamonds %>% 
  mutate(cut = fct_relevel(cut, sort))
levels(diamondssort$cut)
## [1] "Fair"      "Good"      "Ideal"     "Premium"   "Very Good"
#randomly selects them
diamondssample <- diamonds %>% 
  mutate(cut = fct_relevel(cut, sample))
levels(diamondssample$cut)
## [1] "Good"      "Premium"   "Very Good" "Ideal"     "Fair"
#reverses the order
diamondsrev <- diamonds %>% 
  mutate(cut = fct_relevel(cut, rev))
levels(diamondsrev$cut)
## [1] "Ideal"     "Premium"   "Very Good" "Good"      "Fair"

Lastly, remember that you cannot use it to create new levels.

diamonds <- diamonds %>% 
  mutate(cut = fct_relevel(cut, "Fake",after=1))
## Warning: Unknown levels in `f`: Fake
levels(diamonds$cut)
## [1] "Fair"      "Good"      "Very Good" "Premium"   "Ideal"

Is it helpful?

fct_relevel is helpful if you have many factor levels and only need to switch a few things around.