Compare strings with logical operator in R
66,768
Instead of using sapply
to loop through each individual day in x
and check whether it's the weekday or weekend, you can do this in a single vectorized operation with ifelse
and %in%
:
ifelse(x %in% c("Sat", "Sun"), "Weekend", "Weekday")
# [1] "Weekday" "Weekday" "Weekday" "Weekday" "Weekday" "Weekend" "Weekend"
The motivation for using vectorized operations here is twofold -- it will save you typing and it will make your code more efficient.
Author by
Bridgbro
Updated on August 12, 2020Comments
-
Bridgbro over 3 years
I'm getting an error trying to compare and set weekday string values as either a "weekend" or a "weekday" using R. Any suggestions on how to approach this problem in a better way would be great.
x <- c("Mon","Tue","Wed","Thu","Fri","Sat","Sun") setDay <- function(day){ if(day == "Sat" | "Sun"){ return("Weekend") } else { return("Weekday") } } sapply(x, setDay)
This is the error I get back in RStudio:
Error in day == "Sat" | "Sun" : operations are possible only for numeric, logical or complex types
-
Frank over 8 yearsAnd as a counter to the
ifelse
hate:c("Weekend", "Weekday")[1L+x %in% c("Sat", "Sun")]
-
josliber over 8 years@Frank I understand the motivation for that sort of expression instead of
ifelse
, but I find it to be a lot less readable. -
Señor O over 8 years^^ especially the
1L
- is that even necessary? -
Frank over 8 yearsI'm with you; just trying to guard against an unnecessary answer with that approach :)
-
josliber over 8 years@SeñorO you add the 1 to convert
FALSE
andTRUE
to indices 1 and 2, respectively. -
Señor O over 8 yearsYeah, but the
L
specifies that it's an integer, which is used sometimes in highly optimized code, which this doesn't need to be. I think[1 + x %in% c(...)]
would be more readable? -
josliber over 8 yearsAh gotcha, you're saying 1L versus 1. I also noticed in this particular case that it should be
c("Weekday", "Weekend")[1L+x %in% c("Sat", "Sun")]
instead (flip the first vector). -
ExperimenteR over 8 years
ifelse("Sunday" %in% c("Sat", "Sun"), "Weekend", "Weekday")
-
josliber over 8 years@ExperimenteR well, from the question it seems like it's going to be "Sun" instead of "Sunday" -- note that the OP's original code (with the bug fix) will also return "Weekday" in this case. Of course, you could defend against the fully spelled days by checking for inclusion in the set
c("Sat", "Sun", "Saturday", "Sunday")
. -
rbatt over 8 yearsalso, if
%in%
syntax confuses you, you can useis.element()
(although takes up more characters) -
MichaelChirico over 8 yearsOnce we start allowing Sunday, Saturday, Sat, etc., it's time to regex:
ifelse(grepl("sun|sat",tolower(x)),"Weekend","Weekday")
-
MichaelChirico over 8 yearsFor the uninitiated, "the motivation for that sort of expression" is here