Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recoding all variables based on conditions

I'm trying to recode all the variables in my dataset that are on an "agree/disagree" scale to numeric values. I've tried using mutate_all and case_when, but then it returns NA values for variables like the id column and var3(data below). Here's the code I was using:

newdat <- olddat %>% mutate_all(funs(case_when(. == "Strongly Disagree (1)" ~ 1,
                                               . == "Disagree (2)" ~ 2,
                                               . == "Neutral (3)" ~ 3,
                                               . == "Agree (4)" ~ 4,
                                               . == "Strongly Agree (5)" ~ 5)))

What I want to happen is below:

HAVE DATA

id     var1                      var2           var3      var4
 1     Strongly Disagree (1)     Agree (4)      5         Agree (4)
 2     Strongly Disagree (1)     Neutral (3)    6         Neutral (3)
 3     Disagree (2)              Neutral (3)    4         Strongly Agree (5)
 4     Strongly Disagree (1)     Agree (4)      9         Disagree (2)
 5     Neutral (3)               Agree (4)      2         Agree (4)

WANT DATA

id     var1   var2   var3   var4
 1     1      4      5      4
 2     1      3      6      3
 3     2      3      4      5
 4     1      4      9      2
 5     3      4      2      4

P.S. Tried searching for an existing answer to this but I couldn't find one! Maybe I was phrasing something wrong?

like image 429
L. Tucker Avatar asked Jul 21 '26 19:07

L. Tucker


2 Answers

You can simply extract the numeric code from each cell since you already have it in parenthesis. No need to recode. Here's a way using stringr::str_extract() -

have %>% 
  mutate_at(vars(starts_with("var")), ~as.integer(str_extract(x, "[0-9]")))
like image 179
Shree Avatar answered Jul 23 '26 10:07

Shree


You need to use mutate_at instead of mutate_all as you want to change only selected columns because by default in case_when the values which are not matched are turned to NA.

library(dplyr)

df %>% mutate_at(vars(var1, var2, var4), 
                     ~(case_when(. == "Strongly Disagree (1)" ~ 1,
                                 . == "Disagree (2)" ~ 2,
                                 . == "Neutral (3)" ~ 3,
                                 . == "Agree (4)" ~ 4,
                                 . == "Strongly Agree (5)" ~ 5)))

#  id var1 var2 var3 var4
#1  1    1    4    5    4
#2  2    1    3    6    3
#3  3    2    3    4    5
#4  4    1    4    9    2
#5  5    3    4    2    4

As there are many columns to do this, we can first find out which columns need to change and then use mutate_at

cols <- which(colSums(sapply(df, grepl, pattern =  "Agree|Disagree")) > 0)

df %>%
    mutate_at(cols, ~case_when(. == "Strongly Disagree (1)" ~ 1,
                    . == "Disagree (2)" ~ 2,
                    . == "Neutral (3)" ~ 3,
                    . == "Agree (4)" ~ 4,
                    . == "Strongly Agree (5)" ~ 5))
like image 22
Ronak Shah Avatar answered Jul 23 '26 11:07

Ronak Shah