Skip to contents

Reorder factor levels

Usage

reorder_levels(x, new_order, warn_drop_order = TRUE)

Arguments

x

factor with levels to be reordered to new_order, or character vector to be converted to a factor with levels ordered as new_order. Should have length larger than zero.

new_order

a character vector with a length larger than zero containing unique levels giving the desired order, or NULL to sort levels on increasing numerical value.

warn_drop_order

TRUE or FALSE: warn if values of new_order are dropped because they are not present in x?

Value

x after converting it to a factor with levels reordered to new_order, dropping values in new_order that are not present in x.

Details

Character input to x is silently converted to a factor before reordering the factor levels.

Values of factor x that are not present in its levels are added to its levels, and levels that are not present in its values are dropped, both with a warning.

Levels of x that are missing from new_order are appended to new_order, with a warning. Values of new_order that are missing from levels of x are dropped, with a warning if warn_drop_order is TRUE.

Sorting on on increasing numerical value only works if x can be suitably converted by as.numeric_safe().

Notes

Reordering levels of factor f by replacing levels through code like levels(f) <- levels(f)[<some order>] does not work, see the last Example.

See also

stats::relevel() to assign one reference level to a factor; order(); sort()

Other functions to convert types: as.numeric_safe(), reexports, vect_to_char()

Other functions to modify factors: as.numeric_safe(), reexports, replace_vals(), vect_to_char()

Other functions to modify sorting order: reorder_cols()

Examples

orig <- factor(letters[c(12:13, 13:11)], levels = letters[13:11])
orig
#> [1] l m m l k
#> Levels: m l k
reorder_levels(x = orig, new_order = letters[11:13])
#> [1] l m m l k
#> Levels: k l m

x_num <- factor(c(28, 3:2), levels = c(28, 3:2))
# Correctly sorts level 28 after 2 and 3
reorder_levels(x_num, new_order = NULL)
#> [1] 28 3  2 
#> Levels: 2 3 28

# Incorrectly sorts level "28" between "2" and "3"
sort(levels(x_num))
#> [1] "2"  "28" "3" 

# Changing the levels directly does *not* work because it changes the values
levels(orig) <- letters[11:13]
orig
#> [1] l k k l m
#> Levels: k l m