Search code examples
rcovariancerollapply

How to compute rolling covariance more efficiently


I am trying to compute a rolling covariance between a set of data (each column of my x variable) and one other (y variable) in R. I thought I could use one of the apply functions, but can not find how to roll two set of inputs at the same time. Here is what I tried :

 set.seed(1)
 x<-matrix(rnorm(500),nrow=100,ncol=5)
 y<-rnorm(100)
 rollapply(x,width=5,FUN= function(x) {cov(x,y)})
 z<-cbind(x,y)
 rollapply(z,width=5, FUN=function(x){cov(z,z[,6])})

But none is doing what I would like. One solution I found is to use a for loop, but wondering if I can be more efficient in R than :

dResult<-matrix(nrow=96,ncol=5)
for(iLine in 1:96){
    for(iCol in 1:5){
        dResult[iLine,iCol]=cov(x[iLine:(iLine+4),iCol],y[iLine:(iLine+4)])
    }
}

which gives me the expected result :

head(dResult)


           [,1]       [,2]        [,3]        [,4]        [,5]
[1,]  0.32056460 0.05281386 -1.13283586 -0.01741274 -0.01464430
[2,] -0.03246014 0.78631603 -0.34309778  0.29919297 -0.22243572
[3,] -0.16239479 0.56372428 -0.27476604  0.39007645  0.05461355
[4,] -0.56764687 0.09847672  0.11204244  0.78044096 -0.01980684
[5,] -0.43081539 0.01904417  0.01282632  0.35550327  0.31062580
[6,] -0.28890607 0.03967327  0.58307743  0.15055881  0.60704533

Solution

  • set.seed(1)
    x<-as.data.frame(matrix(rnorm(500),nrow=100,ncol=5))
    y<-rnorm(100)
    
    library(zoo)
    
    covResult = sapply(x,function(alpha) {
    
    cov_value = rollapply(cbind(alpha,y),width=5,FUN = function(beta) cov(beta[,1],beta[,2]),by.column=FALSE,align="right") 
    
    return(cov_value)
    
    })
    
    head(covResult)
    #              V1         V2          V3          V4          V5
    #[1,]  0.32056460 0.05281386 -1.13283586 -0.01741274 -0.01464430
    #[2,] -0.03246014 0.78631603 -0.34309778  0.29919297 -0.22243572
    #[3,] -0.16239479 0.56372428 -0.27476604  0.39007645  0.05461355
    #[4,] -0.56764687 0.09847672  0.11204244  0.78044096 -0.01980684
    #[5,] -0.43081539 0.01904417  0.01282632  0.35550327  0.31062580
    #[6,] -0.28890607 0.03967327  0.58307743  0.15055881  0.60704533
    

    Also check out:

    library(PerformanceAnalytics)
    ?chart.rollingCorrelation