Felix
Felix

Reputation: 224

Set day of week to be used by to.weekly

I am trying to convert a time series of daily data (only business days) contained in an xts object into a time series of weekly data. Specifically, I want the resulting time series to contain the end of week entries (meaning last business day of a week) of the original data. I've been trying to achieve this using the function to.weekly of the xts package.

In the discussion regarding another question (Wrong week-ending date using 'to.weekly' function in 'xts' package) the below example code achieved exactly what I need. However, when I run the code, to.weekly uses Mondays as a representative for the weekly data.

I am wondering which global setting might allow me to force to.weekly to use Friday as a week's representative.

Example code:

library(lubridate); library(xts)   
test.dates <- seq(as.Date("2000-01-01"),as.Date("2011-10-01"),by='days')
test.dates <- test.dates[wday(test.dates)!=1 & wday(test.dates)!=7] #Remove weekends
test.data <- rnorm(length(test.dates),mean=1,sd=2)
test.xts <- xts(x=test.data,order.by=test.dates)
test.weekly <- to.weekly(test.xts)
test.weekly[wday(test.weekly, label = TRUE, abbr = TRUE) != "Fri"]

Upvotes: 3

Views: 1937

Answers (2)

I had the same problem and I found a two-lines solution.

You need first to retain only business days (if your data set also contains holidays):

test.dates <- test.dates[ wday(dates) %in% c(2:6) ]

Then you have two alternatives. First, you can use to.weekly() which retains the most recent business day, i.e. not necessarily constrained to wday(test.dates)==6

test.weekly <- to.weekly(test.xts)

Or you can use the function endpoints() which works on multi-columns xts objects and deals much better with NA's because it does not remove missing data (preventing the warning "missing values removed from data")

test.weekly <- test.xts[endpoints(test.xts,on='weeks')[-1],]

Upvotes: 0

IRTFM
IRTFM

Reputation: 263481

test.dates <- test.dates[wday(test.dates)==6]
tail(wday(test.dates, label = TRUE, abbr = TRUE))
#[1] Fri Fri Fri Fri Fri Fri
#Levels: Sun < Mon < Tues < Wed < Thurs < Fri < Sat

OK. With the unstated requirements added to the problem:

require(timeDate)
require(lubridate)
 startDate <- as.Date("2000-01-03")
 endDate <- as.Date("2011-10-01")
 AllDays <- as.timeDate(seq(startDate, endDate, by="day"))
 is.wrk <- isBizday(AllDays, holidays = holidayNYSE(), wday = 1:5)
 is.wrkdt <- as.Date(names(is.wrk)[is.wrk])
 endweeks <- tapply(is.wrkdt, paste(year(is.wrkdt),week(is.wrkdt), sep = ""), max)
 head(as.Date(endweeks, origin="1970-01-01"))
#           1            2            3            4            5            6 
#"2011-01-06" "2011-01-13" "2011-01-20" "2011-01-27" "2011-02-03" "2011-02-10" 

So you want:

 as.Date(endweeks, origin="1970-01-01")

Upvotes: 0

Related Questions