简体   繁体   中英

Sequence of last observation of months in a series of dates in R

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.

Here's a two-step process to get the job done:

  1. Use lubridate::ceiling_date to get the first day of next month
  2. We generate a sequence "by month" and subtract 1 day

# 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

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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM