I\'m trying to figure out of how to create a vector of dates of third Fridays of a month for the past 3 years
Thank you in Advance
To round it off, here's a messy way to do it with base
functions:
d <- seq(as.Date("2000/1/1"), by = 1, length.out = 500)
sort(as.Date(tapply(d[which(format(d, '%a')=='Fri')],
format(d[which(format(d, '%a')=='Fri')], '%m-%Y'),
function(x) x[3]), origin='1970-01-01'))
The RcppBDT package wraps a number of date (and related time) calculations from Boost Date_Time.
Among them is a function doing what you want here:
R> getNthDayOfWeek(third, Fri, Apr, 2014)
[1] "2014-04-18"
R>
Instead of the (package-local) constants Jan, Feb, ... you can also use integers to fill you past thiry-sixth months.
Here is a simple (ugly) hack for the sequence:
R> dates <- data.frame(mon=c(5:12, 1:12, 1:12, 1:4),
+ year=c(rep(2011,8), rep(2012,12),
+ rep(2013,12), rep(2014,4)))
R> sapply(1:36, function(i)
+ format(getNthDayOfWeek(third, Fri, dates[i,1], dates[i,2])))
[1] "2011-05-20" "2011-06-17" "2011-07-15" "2011-08-19"
[5] "2011-09-16" "2011-10-21" "2011-11-18" "2011-12-16"
[9] "2012-01-20" "2012-02-17" "2012-03-16" "2012-04-20"
[13] "2012-05-18" "2012-06-15" "2012-07-20" "2012-08-17"
[17] "2012-09-21" "2012-10-19" "2012-11-16" "2012-12-21"
[21] "2013-01-18" "2013-02-15" "2013-03-15" "2013-04-19"
[25] "2013-05-17" "2013-06-21" "2013-07-19" "2013-08-16"
[29] "2013-09-20" "2013-10-18" "2013-11-15" "2013-12-20"
[33] "2014-01-17" "2014-02-21" "2014-03-21" "2014-04-18"
R>
Note that I used format()
which converts to character; else the date turns into numeric. That is just a side-effect of sapply()
though, and you could e.g. assign the Date
type back into the data frame dates
we use here.
The timeDate
package has something very similar:
library(timeDate)
tS = timeSequence(from = "2010-01-01", to = "2013-12-31", by = "month")
timeNthNdayInMonth(tS, nday = 5, nth = 3, format = "%Y-%m-%d")
## GMT
## [1] [2010-01-15] [2010-02-19] [2010-03-19] [2010-04-16] [2010-05-21] [2010-06-18] [2010-07-16]
## [8] [2010-08-20] [2010-09-17] [2010-10-15] [2010-11-19] [2010-12-17] [2011-01-21] [2011-02-18]
## [15] [2011-03-18] [2011-04-15] [2011-05-20] [2011-06-17] [2011-07-15] [2011-08-19] [2011-09-16]
## [22] [2011-10-21] [2011-11-18] [2011-12-16] [2012-01-20] [2012-02-17] [2012-03-16] [2012-04-20]
## [29] [2012-05-18] [2012-06-15] [2012-07-20] [2012-08-17] [2012-09-21] [2012-10-19] [2012-11-16]
## [36] [2012-12-21] [2013-01-18] [2013-02-15] [2013-03-15] [2013-04-19] [2013-05-17] [2013-06-21]
## [43] [2013-07-19] [2013-08-16] [2013-09-20] [2013-10-18] [2013-11-15] [2013-12-20]
Alternative base solution giving the same result using @jbaums' data again:
d <- seq(as.Date("2000/1/1"), by = 1, length.out = 500)
d <- as.POSIXlt(d)
d <- d[d$wday==5]
as.Date(d[ave(d$mon,list(d$mon,d$year),FUN=seq_along)==3])