Replace values from a column with value corresponding to vector with matches

Viewed 194

I have a dataframe and in the column "roles", each row has a value of "students" or "teacher". I want to replace these values with "st" or "te" accordingly.

roles_complete <- c("students","teacher")
roles_standard <- c("st", "te")
data$roles <- stri_replace_all(data$roles, regex= roles_complete, roles_standard)

Weirdly, this only changes some values.

    roles
1   st
2   students
3   teacher
4   te
5   st
6   students
7   teacher
8   te
9   st
10  students
11  teacher
12  te

I'm obviously doing something wrong with the conditions I've inserted in the stri_replace but the documentation is not very clear.

5 Answers

dplyr package

You can use recode() in dplyr.

library(dplyr)

df %>%
  mutate(roles = recode(roles, "students" = "st", "teacher" = "te"))

If you have assigned roles to variables, then you can take a named vector as input.

roles_complete <- c("students", "teacher")
roles_standard <- c("st", "te")

df %>%
  mutate(roles = recode(roles, !!!setNames(roles_standard, roles_complete)))

stringr package

str_replace_all() in stringr also can take a named vector as input.

library(stringr)

df$roles <- str_replace_all(df$roles, setNames(roles_standard, roles_complete))

base solution

df$role <- factor(df$role, labels = c("st", "te"))

Is that stringi package? It seems to me that only sequence (a vector) of "students" and "teacher" in a row is replaced. So when there are "students" and "students" in a row, it remains unchanged.

If you can switch to package stringr, the function str_replace_all() allows you to define exactly how to replace the matched patterns:

library(stringr)
data <- c("students", "teacher", "students", "teacher")
str_replace_all(data, c("students" = "st", "teacher" = "te"))

So for your case:

data$roles <- str_replace_all(data$roles, c("students" = "st", "teacher" = "te"))

Usually R interprets character vectors as factors. If that is the case in your data set:

data <- data.frame(roles = sample(c("students","teacher"), 12, replace = TRUE))
levels(data$roles)
# [1] "students" "teacher" 
levels(data$roles) <- c("st", "te")
levels(data$roles)
# [1] "st" "te"

Easiest Base R way, assuming each level is either student or teacher as is stated in OP:

levels(data$roles) <- substr(levels(data$roles), 1, 2)

Data

data <-
  data.frame(roles = sample(c("students", "teacher"), 12, replace = TRUE))

You could try

data$roles <- replace(data$roles,roles_complete,roles_standard)
Related