13

How do I subset an xts object to only include weekdays (Mon-Fri, with Saturday and Sunday excluded)?

Kyle Brandt
  • 26,938
  • 37
  • 124
  • 165

2 Answers2

17

Here's what I'd do:

library(xts)
data(sample_matrix)
sample.xts <- as.xts(sample_matrix, descr='my new xts object')
x <-  sample.xts['2007']  
x[!weekdays(index(x)) %in% c("Saturday", "Sunday")]

EDIT: Joshua Ulrich in comments points out a better solution using .indexwday(), one of a family of built-in accessor functions for extracting pieces of the index of xts class objects. Also, like Dirk Eddelbuettel's solution, the following should be locale-independent:

x[.indexwday(x) %in% 1:5]
Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • 2
    I show essentially the same answer, but relying on numeric weekdays which renders it independent of the locale used. – Dirk Eddelbuettel Jan 31 '12 at 22:58
  • 9
    +1 Note there's the `.indexwday` function, so your last line could also be: `x[.indexwday(x) %in% 1:5]`. – Joshua Ulrich Jan 31 '12 at 23:00
  • @DirkEddelbuettel Thanks for pointing that out (and +1 chez vous). I wouldn't have appreciated the difference otherwise. – Josh O'Brien Jan 31 '12 at 23:00
  • @JoshO'Brien: Well, I happened to have read the `help(weekdays)` page after `weekdays` annoyed me *again* by not giving numeric results. – Dirk Eddelbuettel Jan 31 '12 at 23:06
  • @JoshuaUlrich Hiya. Has **xts** indexing changed so that this should now be `x[.indexwday(x) %in% 0:4]` ? – Josh O'Brien May 11 '16 at 15:54
  • 1
    No, it hasn't changed. Though there is a bug (timezone isn't used in the conversion) in the xts version on CRAN. That might be the cause of the issue in the proposed edit. – Joshua Ulrich May 11 '16 at 16:45
  • @JoshuaUlrich OK. Thanks. It's 10AM on a Wednesday here on the west coast of the US, and doing `.indexwday(as.xts(Sys.Date()))` (on a Windows machine, running the CRAN version) returns a `2`, so it looked to me like that person was on to something... (Running [the example here](http://stackoverflow.com/a/11871739/980833) also gets me wrong results, returning Tuesdays instead of Mondays.) – Josh O'Brien May 11 '16 at 16:52
7

By computing the day-of-the week given the date, and subsetting. In the example, I use a Date type but the cast to POSIXlt works the same way for POSIXct intra-day timestamps.

> mydates <- Sys.Date() + 0:6
> mydates
[1] "2012-01-31" "2012-02-01" "2012-02-02" "2012-02-03" "2012-02-04" 
+   "2012-02-05" "2012-02-06"
> we <- sapply(mydates, function(d) { as.POSIXlt(d)$wday}) %in% c(0, 6)
> we
[1] FALSE FALSE FALSE FALSE  TRUE  TRUE FALSE
> mydates[ ! we ]
[1] "2012-01-31" "2012-02-01" "2012-02-02" "2012-02-03" "2012-02-06"
> 

This really is not an xts question but basic date handling.

Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725