Search code examples
rfixedrolling-computation

Construct a "simple" fixed rolling window


Is it possible to construct a "simple" fixed rolling window? Say I have the following dataset:

         Apple Microsoft     Tesla    Amazon
 2010 0.8533719 0.8078440 0.2620114 0.1869552
 2011 0.7462573 0.5127501 0.5452448 0.1369686
 2012 0.7580671 0.5062639 0.7847919 0.8362821
 2013 0.3154078 0.6960258 0.7303597 0.6057027
 2014 0.4741735 0.3906580 0.4515726 0.1396147
 2015 0.4230036 0.4728911 0.1262413 0.7495193
 2016 0.2396552 0.5001825 0.6732861 0.8535837
 2017 0.2007575 0.8875209 0.5086837 0.2211072
#I want to be able to produce the following result
s.matrix <- x[1:4,] 
#For the next period, I want to drop the first period and add the next period: 
s.matrix <- x[2:5,] 
#For the rest of the dataset it should be:
 x[3:6,], x[4:7,], x[5:8,]
#That is, the width should always be equal to four. 

I know that lapply is able to do something similar, but then I have to set a fixed value such that it only adds the new variables to an already existing matrix without removing the first observation....or am I wrong?


Solution

  • Assuming x is a data.frame as in the Note at the end, use rollapply to get the desired indexes and apply to generate the corresponding list of data frames.

    library(zoo)
    
    apply(rollapply(1:nrow(x), 4, c), 1, function(ix) x[ix, ])
    

    giving:

    [[1]]
           Apple Microsoft   Tesla  Amazon
    2010 0.85337   0.80784 0.26201 0.18696
    2011 0.74626   0.51275 0.54524 0.13697
    2012 0.75807   0.50626 0.78479 0.83628
    2013 0.31541   0.69603 0.73036 0.60570
    
    [[2]]
           Apple Microsoft   Tesla  Amazon
    2011 0.74626   0.51275 0.54524 0.13697
    2012 0.75807   0.50626 0.78479 0.83628
    2013 0.31541   0.69603 0.73036 0.60570
    2014 0.47417   0.39066 0.45157 0.13961
    
    [[3]]
           Apple Microsoft   Tesla  Amazon
    2012 0.75807   0.50626 0.78479 0.83628
    2013 0.31541   0.69603 0.73036 0.60570
    2014 0.47417   0.39066 0.45157 0.13961
    2015 0.42300   0.47289 0.12624 0.74952
    
    [[4]]
           Apple Microsoft   Tesla  Amazon
    2013 0.31541   0.69603 0.73036 0.60570
    2014 0.47417   0.39066 0.45157 0.13961
    2015 0.42300   0.47289 0.12624 0.74952
    2016 0.23966   0.50018 0.67329 0.85358
    
    [[5]]
           Apple Microsoft   Tesla  Amazon
    2014 0.47417   0.39066 0.45157 0.13961
    2015 0.42300   0.47289 0.12624 0.74952
    2016 0.23966   0.50018 0.67329 0.85358
    2017 0.20076   0.88752 0.50868 0.22111
    

    Note

    We used this for x:

    Lines <- "         Apple Microsoft     Tesla    Amazon
     2010 0.8533719 0.8078440 0.2620114 0.1869552
     2011 0.7462573 0.5127501 0.5452448 0.1369686
     2012 0.7580671 0.5062639 0.7847919 0.8362821
     2013 0.3154078 0.6960258 0.7303597 0.6057027
     2014 0.4741735 0.3906580 0.4515726 0.1396147
     2015 0.4230036 0.4728911 0.1262413 0.7495193
     2016 0.2396552 0.5001825 0.6732861 0.8535837
     2017 0.2007575 0.8875209 0.5086837 0.2211072"
    
    x <- read.table(text = Lines)