Function to Recode Multiple Satisfaction Scale Variables with Standard Evaluation, Forcats, and Stringr

203 views Asked by At
library(tidyverse)
library(stringr)
library(lazyeval)

Below is the data for a simple dataframe example...

Respondent<-c("Respondent1","Respondent2","Respondent3","Respondent4","Respondent5")
Sat1<-c("1 Extremely dissatisfied","2 Moderately dissatisfied","2 Moderately Dissatisfied","4 Neutral","7 Extrmely satified")
Sat2<-c("7 Extremely Satisfied","2. Moderately dissatisfied","4 Neutral","3  Slightly dissatisfied","3 Slightly Dissatisfied")
Sat3<-c("1 Extremely dissatisfied","7 Extremely satisfied","6 Moderately satisfied","4. Neutral","3 Slightly dissatisfied")
Pet<-c("Cat","Cat","Dog","Hamster","Rabbit")

df <- data_frame(Respondent,Sat1,Sat2,Sat3,Pet)

The code below is to recode the satisfaction score columns into the three categories of satisfied, dissatisfied, and neutral.

df %>% 
mutate_at(vars(starts_with("Sat")), 
     funs(fct_collapse(factor(str_sub(., 1, 1), levels = as.character(1:7)),
                          Satisfied = c("7","6","5"),
                          Dissatisfied =c ("3", "2","1"),
                          Neutral = "4")))

However, my real example involves recoding the same satisfaction scale for multiple files, each with a different number of satisfaction scale columns. So I would like to wrap this into a function that will allow me to enter in the dataframe name, as well as any number of columns to recode. Below is one variant of the code that I'm trying to use but I cannot get it to work. I've been playing around with .dots, and "...", but couldn't find anything that works.

 REC<-function(data,...){
data %>% 
 mutate_at(vars(...), 
     funs(fct_collapse(factor(str_sub(., 1, 1), levels = as.character(1:7)),
                   Satisfied = c("7","6","5"),
                   Dissatisfied =c ("3", "2","1"),
                   Neutral = "4")))
                   }

Should I be using standard evaluation with mutate_at? Also, do I have to use .dots with the ...? If standard evaluation doesn't work with mutate_at, I'm open to using other functions/techniques to achieve the same end goal, preferrably within the tidyverse.

1

There are 1 answers

0
FlorianGD On BEST ANSWER

Does starts_with("Sat") work for all your files ? If so the function will work regardless of how many columns starting with "Sat" there are.

REC <- function(data){
  data %>% 
    mutate_at(vars(starts_with("Sat")),
                   funs(fct_collapse(factor(str_sub(., 1, 1), levels = as.character(1:7)),
                                     Satisfied=c("7","6","5"),
                                     Dissatisfied=c("3", "2","1"),
                                     Neutral="4")))
} 

If you want to pass along the indices of the columns you want to change, you can try :

REC <- function(data, variable){
  data %>% 
    mutate_at(vars(variable),
              funs(fct_collapse(factor(str_sub(., 1, 1), levels = as.character(1:7)),
                                    Satisfied=c("7","6","5"),
                                    Dissatisfied=c("3", "2","1"),
                                    Neutral="4")))
}  

Then REC(df, 2:4) will give you this output

# A tibble: 5 × 5
   Respondent         Sat1         Sat2         Sat3     Pet
        <chr>       <fctr>       <fctr>       <fctr>   <chr>
1 Respondent1 Dissatisfied    Satisfied Dissatisfied     Cat
2 Respondent2 Dissatisfied Dissatisfied    Satisfied     Cat
3 Respondent3 Dissatisfied      Neutral    Satisfied     Dog
4 Respondent4      Neutral Dissatisfied      Neutral Hamster
5 Respondent5    Satisfied Dissatisfied Dissatisfied  Rabbit