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.