How do I find the last weekday (e.g., Wednesday) of the month using R? In the code below, I calculate the month, day of the month, week of the month, and weekday. There are 5 Wednesdays in January 2014, but only 4 Wednesdays in February 2014, so I cannot use max(week of the month) as a filter. Any help is appreciated although I prefer to use the base R functions.
DF <- data.frame(DATE = seq(as.Date("2014-01-01"), as.Date("2014-12-31"), "day"))
DF$MONTH <- as.numeric(format(DF$DATE, "%m"))
DF$DAY_OF_MONTH <- as.numeric(format(DF$DATE, "%d"))
DF$WEEK_OF_MONTH <- ceiling(as.numeric(format(DF$DATE, "%d")) / 7)
DF$WEEKDAY <- format(DF$DATE, "%A")
DF
The last date of the month in R You can do it with the ceiling_date function from lubridate. If you use it by itself, then you will get the first date of next month. With simple subtraction, you can gate the last date of a given month.
Example 1: Get Week Number of Date Using strftime() Function The RStudio console returns the result – The week number that corresponds to our example date is the number 40.
I think this is what you're after:
DF$last_weekday_o_month <- ave(
weekdays(DF$DATE),
months(DF$DATE),
FUN = function(x) tail(x[ !(x %in% c("Saturday","Sunday")) ], 1)
)
To find the particular date that is the last weekday....
DF$last_weekdaydate_o_month <- ave(
DF$DATE,
months(DF$DATE),
FUN = function(x) tail(x[ !(weekdays(x) %in% c("Saturday","Sunday")) ], 1)
)
the result looks like...
DATE last_weekday_o_month last_weekdaydate_o_month
1 2014-01-01 Friday 2014-01-31
2 2014-01-02 Friday 2014-01-31
3 2014-01-03 Friday 2014-01-31
4 2014-01-04 Friday 2014-01-31
5 2014-01-05 Friday 2014-01-31
6 2014-01-06 Friday 2014-01-31
...
360 2014-12-26 Wednesday 2014-12-31
361 2014-12-27 Wednesday 2014-12-31
362 2014-12-28 Wednesday 2014-12-31
363 2014-12-29 Wednesday 2014-12-31
364 2014-12-30 Wednesday 2014-12-31
365 2014-12-31 Wednesday 2014-12-31
If you did this first, of course you could compute last_weekday_o_month
as weekdays(last_weekdaydate_o_month)
.
With a couple packages, this can be done more elegantly/readably, as suggested by @RichardScriven:
library(data.table)
setDT(DF)[,
last_weekdaydate_o_month := last(DATE[!chron::is.weekend(DATE)])
, by = month(DATE)]
which gives
DATE last_weekdaydate_o_month
1: 2014-01-01 2014-01-31
2: 2014-01-02 2014-01-31
3: 2014-01-03 2014-01-31
4: 2014-01-04 2014-01-31
5: 2014-01-05 2014-01-31
---
361: 2014-12-27 2014-12-31
362: 2014-12-28 2014-12-31
363: 2014-12-29 2014-12-31
364: 2014-12-30 2014-12-31
365: 2014-12-31 2014-12-31
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With