I have a vector of date objects (yyyy-mm-dd
) and I want to determine if any of them are on weekend or not. Is there a function that can determine this straighta
I put @AnandaMahto's suggestion here rather than a comment:
library(chron)
x <- seq(Sys.Date()-10, Sys.Date(), by = 1)
x[is.weekend(x)]
## [1] "2014-10-11" "2014-10-12" "2014-10-18"
The wday
in both lubridate
and data.table
(yes, data.table
has pretty much everything but the kitchen sink :-) both do a variation on:
as.POSIXlt(x, tz = tz(x))$wday + 1 # lubridate
as.POSIXlt(x)$wday + 1L # data.table
So you could, in theory, just do:
as.POSIXlt("2014-10-18")$wday + 1
## [1] 7
and then test for the weekend days as other answer(s) do.
After looking a lot about this topic, I found this solution particularly simple using the package RQuantLib
install.packages("RQuantLib")
library(RQuantLib)
isBusinessDay(calendar="WeekendsOnly", dates=yourdatesofinterest)
You can modify this code with different calendars to add to the weekends different sets of holidays in different countries (below just an example, but they have many more).
isBusinessDay(calendar="UnitedStates", dates=yourdatesofinterest)
isBusinessDay(calendar="UnitedStates/Settlement", dates=yourdatesofinterest)
isBusinessDay(calendar="UnitedStates/NYSE", dates=yourdatesofinterest)
isBusinessDay(calendar="Sweden", dates=yourdatesofinterest)
isBusinessDay(calendar="Mexico", dates=yourdatesofinterest)
I hope it helps somebody
Using lubridate to avoid other packages, you can use:
is_weekday = function(timestamp){
lubridate::wday(timestamp, week_start = 1) < 6
}
You can use the base R function weekdays()
.
x <- seq(Sys.Date() - 10, Sys.Date(), by = 1)
weekdays(x, abbr = TRUE)
# [1] "Wed" "Thu" "Fri" "Sat" "Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"
x[grepl("S(at|un)", weekdays(x))]
# [1] "2014-10-11" "2014-10-12" "2014-10-18"
As far as lubridate goes, wday()
has a label
argument. When set to TRUE
, the (abbreviated) day names are returned instead of numbers. Use the abbr
argument to change to full names.
library(lubridate)
wday(x, label = TRUE)
# [1] Wed Thurs Fri Sat Sun Mon Tues Wed Thurs Fri Sat
# Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat
Another approach could be to use format
and %u
, which gives a number for the day of the week, starting with "1" representing "Monday".
With that, you can do:
x <- seq(as.Date("2014-10-18")-10, Sys.Date(), by = 1)
format(x, "%u") %in% c(6, 7)
# [1] FALSE FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE TRUE
x[format(x, "%u") %in% c(6, 7)]
# [1] "2014-10-11" "2014-10-12" "2014-10-18"