Rafael
Rafael

Reputation: 3196

Faster way to subset xts

I have a large xts that I want to filter by month and by date for every year present.

library(xts)   
junk <- xts(sample.int(101, size = 1461, replace = T), seq(as.Date('2006-01-01'), as.Date('2009-12-31'), 'days'))
junk_sma10 = TTR::SMA(x = junk, n = 10) ## trailing 10 day avg

Right now I'md doing it via a loop for every day and month value which takes a while. I know R is better at doing things vectors at a time.

months_filtered <- idx_apcp30[.indexmon(junk_sma10) == 1]     ## filter for feb
final_filtered <- months_filtered[.indexmday(months_filtered) == 15] ## filter for 16th

The output is a unique xts for every day of the year.

           SMA
2006-02-16 61.0
2007-02-16 50.5
2008-02-16 60.5
2009-02-16 54.1

and then the next iteration (+1 mday) would produce

            SMA
2006-02-17 64.3
2007-02-17 48.4
2008-02-17 66.1
2009-02-17 48.6

I need to produce and store every xts that this process produces. How do I do this not in a loop?

I found a solution like this:

junk[seq(as.Date('2006-01-01'),as.Date('2009-12-31'),by='year')]

But I would still have to iterate over every day...

Upvotes: 1

Views: 172

Answers (1)

Joshua Ulrich
Joshua Ulrich

Reputation: 176648

An easy solution is to split your xts object into chunks by month and day.

# if using xts < 0.10-0 (bug work-around)
month_day <- split(junk_sma10, as.numeric(format(index(junk_sma10), "%m%d")))

# requires xts >= 0.10-0
month_day <- split(junk_sma10, format(index(junk_sma10), "%m%d"))

Now month_day is a list, where every element is the same month and day of the month for each year. Then you can continue your analysis by using lapply to call a function on each list element.

Upvotes: 1

Related Questions