0

I simplified the data df for demonstration purpose.

df<-data.frame(id=c(1,1,3,4,5,6,7),title_1=c("H","M","","M","L","L","H")
               ,title_2=c("M","M","","L","L","L","H")
               ,title_3=c("H","H","M","L","","M","M"))

what I want to do is change the values.If the value is null "", then I want to change it to 0. If the value is H, I want to change it to 3. If the value is M, I want to change it to 2. If the value is L, I want to change it to 1. The reason why I stuck here is because in my actual data, there are so many columns named as titel_1, title_2,title_3, ... ,title_100.So, I cannot type every columns to do this . So I need the code that is applicable to the data that has many columns.

Lee
  • 369
  • 1
  • 6
  • I reckon using a lookup table will be straight-forward and flexible for this sort of thing, as per this old question: https://stackoverflow.com/questions/18456968/how-do-i-map-a-vector-of-values-to-another-vector-with-my-own-custom-map-in-r/18457055 - e.g. `lkup <- data.frame(old = c("", "H", "M", "L"), new=c(0,3,2,1)); df[-1] <- lapply(df[-1], \(x) lkup$new[match(x,lkup$old)] )` – thelatemail Jul 25 '22 at 04:31

2 Answers2

2

You may try

library(dplyr)
df %>%
  mutate(across(everything(), ~replace(., . ==  "", 0)),
         across(everything(), ~replace(., . ==  "H", 3)),
         across(everything(), ~replace(., . ==  "M", 2)),
         across(everything(), ~replace(., . ==  "L", 1))
         )

  id title_1 title_2 title_3
1  1       3       2       3
2  1       2       2       3
3  3       0       0       2
4  4       2       1       1
5  5       1       1       0
6  6       1       1       2
7  7       3       3       2
Park
  • 14,771
  • 6
  • 10
  • 29
1

Another option is to use dplyr::recode

df %>%
    mutate(across(starts_with("title"), recode, "L" = 1, "M" = 2, "H" = 3, .default = 0))
#  id title_1 title_2 title_3
#1  1       3       2       3
#2  1       2       2       3
#3  3       0       0       2
#4  4       2       1       1
#5  5       1       1       0
#6  6       1       1       2
#7  7       3       3       2
Maurits Evers
  • 49,617
  • 4
  • 47
  • 68