Search code examples
rfor-looprollapply

Rolling Window adfTest with fix starting point


So I want to run the adfTest with lag=0 and type="c" in a loop, so the starting window is of length=5 and the finish window is lenght=nrow(Data). The thing is that i want that the starting window is fix so if the data contains 10 data point the first result goes from 1:5, the second 1:6 and so on until it finish with 1:10.

I have try to do it with rollapply but it does not work this way, the code that i have is:

num_dividends <- nrow(C)
rw<-4
sample_interval <- 1 
wi <- list()
DF <- matrix(0, nrow=num_dividends, ncol=num_dividends)
for(i in 1:(num_dividends-rw-1) )  {
  wi <- c(wi,list(list(c(window_size=rw+i,sample_interval=sample_interval),
                       DF=cbind(Date=seq(rw+i, num_dividends, by=sample_interval),
                       statistic=rollapplyr(C$Dividend, rw+i, function(u) adfTest(u)@test$statistic,by=sample_interval,partial=T)))))
  DF[seq((rw+i),num_dividends,sample_interval), i+rw] <- wi[[i]]$DF[,"statistic"]
}

What it does is that it creates a matrix that i use latter for other calculations with the corresponding lost data thanks to the starting window. But the PROBLEM is that the starting window isn't fix, so the first observation goes from 1:5 but the second goes from 2:6; also it calculates the ADF with lag=1 and I don't know how to add the option of the function with the rollapplyr of lag=0.

To make it more clear suppose that I do rollapplyr(C$Dividend, 5, FUN=mean,by=sample_interval) and the subsequent data are the results that i get and what I want.

Dividend    This is What I Want     This is What I Get 
1                    NA                       NA
2                    NA                       NA
3                    NA                       NA
4                    NA                       NA
5                     3                        3
6                    3.5                       4
7                     4                        5
8                    4.5                       6
9                     5                        7

Note that i want to do it in a loop because i want that the width increases each time it finish the loop, until the window is the size of the whole data set.


Solution

  • Reviewing your problem again, it seems that the code can be simplified by replacing rollapply with sapply and eliminating the list wi. Here r1 is start date, r2 is the end date, and the window = r2 - r1 + 1.

      library(zoo)
      library(tseries)
      num_random <- 20
      set.seed(123)
      C <- data.frame(Date=1:num_random, Dividend=550 + 30*rnorm(num_random))  # generate randum sample data
      num_dividends <- nrow(C)
      head(C)
    
      rw_min <- 9         #   minimum window size
      DF2 <- matrix(NA_real_, nrow=num_dividends, ncol= num_dividends-rw_min+1)
      for( r1 in 1:(num_dividends-rw_min + 1))  {
         r2 <- (r1+rw_min-1):num_dividends
         DF2[r2,r1] <- sapply(r2, FUN=function(n) adf.test(C$Dividend[r1:n])$statistic)
      }
      # column indices of DF2 are r1, the start Dates used in the ADF calculation
      # row indices of DF2 are r2, the end Dates of the window used in the ADF calculation 
      # window size = r2-r1+1 
      # For example, DF2[15,1] is the ADF statistic for start Date = 1 and end Date = 15 with window = 15 
      print(DF2, digits=4)
    

    I've benchmarked the rollapply and sapply versions and, for this case, execution times for both versions are the same.