Renaming levels of a factor

Problem

You want to rename the levels in a factor.

Solution

  1. # A sample factor to work with.
  2. x <- factor(c("alpha","beta","gamma","alpha","beta"))
  3. x
  4. #> [1] alpha beta gamma alpha beta
  5. #> Levels: alpha beta gamma
  6. levels(x)
  7. #> [1] "alpha" "beta" "gamma"

The easiest way is to use revalue() or mapvalues() from the plyr package:

  1. library(plyr)
  2. revalue(x, c("beta"="two", "gamma"="three"))
  3. #> [1] alpha two three alpha two
  4. #> Levels: alpha two three
  5. mapvalues(x, from = c("beta", "gamma"), to = c("two", "three"))
  6. #> [1] alpha two three alpha two
  7. #> Levels: alpha two three

If you don’t want to rely on plyr, you can do the following with R’s built-in functions.Note that these methods will modify x directly; that is, you don’t have to save the result back into x.

  1. # Rename by name: change "beta" to "two"
  2. levels(x)[levels(x)=="beta"] <- "two"
  3. # You can also rename by position, but this is a bit dangerous if your data
  4. # can change in the future. If there is a change in the number or positions of
  5. # factor levels, then this can result in wrong data.
  6. # Rename by index in levels list: change third item, "gamma", to "three".
  7. levels(x)[3] <- "three"
  8. x
  9. #> [1] alpha two three alpha two
  10. #> Levels: alpha two three
  11. # Rename all levels
  12. levels(x) <- c("one","two","three")
  13. x
  14. #> [1] one two three one two
  15. #> Levels: one two three

It’s possible to rename factor levels by name (without plyr), but keep in mind that this works only if ALL levels are present in the list; if any are not in the list, they will be replaced with NA.

  1. # Rename all levels, by name
  2. x <- factor(c("alpha","beta","gamma","alpha","beta"))
  3. levels(x) <- list(A="alpha", B="beta", C="gamma")
  4. x
  5. #> [1] A B C A B
  6. #> Levels: A B C

It’s also possible to use R’s string search-and-replace functions to rename factor levels. Note that the ^ and $ surrounding alpha are there to ensure that the entire string matches. Without them, if there were a level named alphabet, it would also match, and the replacement would be onebet.

  1. # A sample factor to work with.
  2. x <- factor(c("alpha","beta","gamma","alpha","beta"))
  3. x
  4. #> [1] alpha beta gamma alpha beta
  5. #> Levels: alpha beta gamma
  6. levels(x) <- sub("^alpha$", "one", levels(x))
  7. x
  8. #> [1] one beta gamma one beta
  9. #> Levels: one beta gamma
  10. # Across all columns, replace all instances of "a" with "X"
  11. levels(x) <- gsub("a", "X", levels(x))
  12. x
  13. #> [1] one betX gXmmX one betX
  14. #> Levels: one betX gXmmX
  15. # gsub() replaces all instances of the pattern in each factor level.
  16. # sub() replaces only the first instance in each factor level.

See also

Mapping values in a vector to new values works much the same. See ../Mapping vector values for more information.