Reputation: 603
If I have a range of business day dates from 2010-01-04
to 2014-12-31
, how do I create a vector of dates containing the last date for each month in my data?
I've looked through zoo and lubridate packages but couldn't find anything relevant.
Upvotes: 0
Views: 248
Reputation: 269714
It's not clear whether you want all end of months for the two dates plus all months between them or just for the two dates but below we show both.
1) Here is a one-liner using the yearmon
class and gives all end of months for the from the first date to the second date. Convert each input character string to yearmon
class, create a sequence of them and convert to Date
class using frac
equals 1 (which means last day of month).
library(zoo)
as.Date(seq(as.yearmon("2010-01-04"), as.yearmon("2014-12-31"), 1/12), frac = 1)
giving:
[1] "2010-01-31" "2010-02-28" "2010-03-31" "2010-04-30" "2010-05-31"
[6] "2010-06-30" "2010-07-31" "2010-08-31" "2010-09-30" "2010-10-31"
[11] "2010-11-30" "2010-12-31" "2011-01-31" "2011-02-28" "2011-03-31"
[16] "2011-04-30" "2011-05-31" "2011-06-30" "2011-07-31" "2011-08-31"
[21] "2011-09-30" "2011-10-31" "2011-11-30" "2011-12-31" "2012-01-31"
[26] "2012-02-29" "2012-03-31" "2012-04-30" "2012-05-31" "2012-06-30"
[31] "2012-07-31" "2012-08-31" "2012-09-30" "2012-10-31" "2012-11-30"
[36] "2012-12-31" "2013-01-31" "2013-02-28" "2013-03-31" "2013-04-30"
[41] "2013-05-31" "2013-06-30" "2013-07-31" "2013-08-31" "2013-09-30"
[46] "2013-10-31" "2013-11-30" "2013-12-31" "2014-01-31" "2014-02-28"
[51] "2014-03-31" "2014-04-30" "2014-05-31" "2014-06-30" "2014-07-31"
[56] "2014-08-31" "2014-09-30" "2014-10-31" "2014-11-30" "2014-12-31"
2) or if you mean you just want the corresponding end of month for each input date then here is a one-liner for that:
library(zoo)
x <- c("2010-01-04", "2014-12-31") # input data
as.Date(as.yearmon(x), frac = 1)
giving:
[1] "2010-01-31" "2014-12-31"
2a) To do this without any packages first define a first of month function and then apply it twice as shown.
fom <- function(x) as.Date(cut(as.Date(x), "month"))
fom(fom(x) + 31) - 1
giving:
[1] "2010-01-31" "2014-12-31"
Upvotes: 2
Reputation: 6073
Here's a two-step process to get the job done:
lubridate::ceiling_date
to get the first day of next month# generage some random dates
set.seed(123)
mydates <- sample(seq(from = as.Date("2017-01-01"),
to = as.Date("2018-12-31"), by="day"), 10)
# generate requested sequence
d1 <- lubridate::ceiling_date(min(mydates), "month")
d2 <- lubridate::ceiling_date(max(mydates), "month")
result <- seq(from=d1, to=d2, by="month") - 1
Upvotes: 2