28
votes
$\begingroup$

I have a time series and I want to subset it while keeping it as a time series, preserving the start, end, and frequency.

For example, let's say I have a time series:

> qs <- ts(101:110, start=c(2009, 2), frequency=4)
> qs
     Qtr1 Qtr2 Qtr3 Qtr4
2009       101  102  103
2010  104  105  106  107
2011  108  109  110     

Now I will subset it:

> qs[time(qs) >= 2010 & time(qs) < 2011]
[1] 104 105 106 107

Notice that I got the correct results, but I lost the "wrappings" from the time series (namely start, end, frequency.)

I'm looking for a function for this. Isn't subsetting a time series is a common scenario? Since I haven't found one yet, here is a function I wrote:

subset.ts <- function(data, start, end) {
  ks <- which(time(data) >= start & time(data) < end)
  vec <- data[ks]
  ts(vec, start=start(data) + c(0, ks[1] - 1), frequency=frequency(data))
}

I'd like to hear about improvements or cleaner ways to do this. In particular, I don't like the way I'm hard-coding start and end. I'd rather let the user specify an arbitrary boolean condition.

$\endgroup$

2 Answers 2

36
votes
$\begingroup$

Use the window function:

> window(qs, 2010, c(2010, 4))
     Qtr1 Qtr2 Qtr3 Qtr4
2010  104  105  106  107
$\endgroup$
1
  • 2
    $\begingroup$ Also note that window(qs,2010, c(2010, 4)) <- 3 will change the qs accordingly. $\endgroup$
    – mpiktas
    Commented Jan 14, 2011 at 6:34
8
votes
$\begingroup$

Also useful, if you are combining multiple time series and don't want to have to have to window every one to get them to match, ts.union and ts.intersect.

$\endgroup$

Not the answer you're looking for? Browse other questions tagged or ask your own question.