Search multiple columns dplyr

Viewed 49

My columns are:

> names(fullmerge.df)
 [1] "Email"               "SID"                 "First.Name"          "Last.Name"          
 [5] "Program"             "Location"            "StudentType"         "SS.Advisor"         
 [9] "CourseTotal"         "Questionnaire"       "Quiz1"               "Quiz2"              
[13] "Quiz3"               "Quiz4"               "Quiz5"               "Quiz6"              
[17] "Quiz7"               "Quiz8"               "Satisfaction.Survey" "F1"                 
[21] "Status"              "Incomplete"          "Retake"             

I'm trying to create a dummy variable in column "Retake" that takes 1 if any Quiz grade (Quiz1 through Quiz8) is below 80.00, and 0 otherwise.

My first thought was I need an ifelse that checks if any values in columns "Quiz1" through "Quiz8" are <80 and in column "Retake" return 1 if any match within row, and 0 if no match. Something like this:

fullmerge.df$Retake <- ifelse(fullmerge.df$Quiz1 <80 |
                                  fullmerge.df$Quiz2 <80 |
                                  fullmerge.df$Quiz3 <80 |
                                  fullmerge.df$Quiz4 <80 |
                                  fullmerge.df$Quiz5 <80 |
                                  fullmerge.df$Quiz6 <80 |
                                  fullmerge.df$Quiz7 <80 |
                                  fullmerge.df$Quiz8 <80
                                , 1 , 0)

I'm also aware of:

starts_with.("Quiz")

...just don't know how to implement.

That being said, the other issue is that all "Quizx" columns are chr. type because they contain strings "-" if the Quiz has not been completed. Column "Quiz4" also contains strings "Not required" as some students don't need to take this quiz.

> unique(fullmerge.df$Quiz4)
[1] "Not required" "80.00"   "100.00"  "-" 
1 Answers

We can use if_any

library(dplyr)
fullmerge.df <- fullmerge.df %>%
     mutate(Retake = +(if_any(starts_with("Quiz"), ~ as.numeric(.) < 80)))

Or an option in base R would be

nm1 <- grep("^Quiz", names(fullmerge.df))
tmp <- fullmerge.df[nm1]
tmp[] <- lapply(tmp, as.numeric)
fullmerge.df$Retake <- +(rowSums(tmp < 80, na.rm = TRUE) > 0)
Related