简体   繁体   中英

How do I recode several columns by name in R in a "tidyverse" way?

I have several columns in a data frame that I'm trying to recode and would like to do it in a way that's more elegant than I'm currently doing.

Here's my data frame:

df <- data.frame(name=c("Joe","Bob","Sue","Tim", "Steve"), 
                 X1=c("Always", "Sometimes", "Often", "Never", NA), 
                 X2=c("Yes", "No", "No", "Yes", "Yes"),
                 X3=c("Sometimes", "Sometimes", "Never", "Always", "Always"))
name    X1          X2    X3
Joe     Always      Yes   Sometimes
Bob     Sometimes   No    Sometimes
Sue     Often       No    Never
Tim     Never       Yes   Always
Steve   NA          Yes   Always

My current method of recoding is quite inelegant:

for(i in c(2, 4)){
  df[,paste(colnames(df), '_recode', sep="")[i]] = ifelse(df[,i] == 'Always', 1, 
                                                                                  ifelse(df[,i] == 'Often', 2,
                                                                                         ifelse(df[,i] == 'Sometimes', 3,
                                                                                                ifelse(df[,i] == 'Never', 4,
                                                                                                       NA))))
}

I'd like to be able to reference the columns by name instead of by index so that the code is more stable. I'd also like to do this in tidyverse if possible. Thanks!

We can use mutate with across . Loop over the columns 2 and 4 in across , use a named vector or a key/value vector to match and replace the values in the column and rename the column with suffix "recode" in .names

library(dplyr)
df1 <- df %>%
      mutate(across(c(2, 4),  ~ setNames(1:4, c("Always", "Often", 
         "Sometimes", "Never"))[.], .names = "{.col}_recode"))

-output

df1
#   name        X1  X2        X3 X1_recode X3_recode
#1   Joe    Always Yes Sometimes         1         3
#2   Bob Sometimes  No Sometimes         3         3
#3   Sue     Often  No     Never         2         4
#4   Tim     Never Yes    Always         4         1
#5 Steve      <NA> Yes    Always        NA         1

You can also use fct_recode from package forcats a member of tidyverse family:

library(tidyverse)

df2 <- df %>%
  mutate(X1 = factor(X1),
         X3 = factor(X3),
         X1 = fct_recode(X1, "1" = "Always", "2" = "Often" , "3" =  "Sometimes", 
                         "4" = "Never"),
         X3 = fct_recode(X3, "1" = "Always", "3" =  "Sometimes", 
                         "4" = "Never"))

   name   X1  X2 X3
1   Joe    1 Yes  3
2   Bob    3  No  3
3   Sue    2  No  4
4   Tim    4 Yes  1
5 Steve <NA> Yes  1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM