TheGoat
TheGoat

Reputation: 2867

Rolling correlation between lists in R

I have two lists, listA and listB which I would like to calculate the correlation between them using a rolling window of size 4.

listA
    A   B   C   D
1)  1   3   4   6
2)  6   9   11  1
3)  1   3   4   5
4)  8   4   5   6
5)  9   9   4   6
6)  1   5   6   6
7)  9   3   6   4
8)  6   7   8   9

listB
    A   B   C   D
1)  1   3   4   3
2)  6   9   5   7
3)  1   1   4   5
4)  7   1   5   6
5)  9   9   3   6
6)  1   5   6   6
7)  9   9   6   4
8)  5   6   4   9

Specifically I wish to calculate the cor(listA[1:4,1],listB[1:4,1]) using a rolling window of size 4 which means I'll have 5 values for the correlation between listA and listB for column A. Once this is done for column A I then would like to do the same for column B, C and D.

I have previously achieved this using 'rollapplyr' but the object I was working on was an XTS object and not two individual objects which for my simple little brain made it easier to comprehend.

'result <- rollapplyr(XTSobject, 4, cor, by.column = FALSE)'

Can anyone suggest a way to do this between two lists?

Upvotes: 0

Views: 788

Answers (2)

Łukasz Deryło
Łukasz Deryło

Reputation: 1860

Let me randomly generate listA and listB and work on them:

listA<-data.frame(matrix(rnorm(32), c(8,4)))
listB<-data.frame(matrix(rnorm(32), c(8,4)))

Then, prepare array for you results:

result<-array(NA, c(5,4))
dimnames(result)<-list(paste0(1:5, '-', 4:8), colnames(listA))

Loop-in-loop now:

for(i in 1:5){
 for (j in 1:4){
  result[i,j]<-cor(listA[i:(i+3),j], listB[i:(i+3),j])
   }
 }

Here is what I got:

result
             X1         X2         X3          X4
1-4 -0.24299058 -0.6359179 -0.3303014  0.46628496
2-5 -0.05606969 -0.9332142 -0.5414745  0.08460162
3-6  0.21371864 -0.5366821 -0.5799187  0.19306623
4-7  0.50005529 -0.4661710  0.2146866  0.49636429
5-8  0.52684198 -0.3768619  0.3599111 -0.93804204

The same could be achieved without looping by using the apply family instead.

Upvotes: 1

Roman
Roman

Reputation: 17648

Using the data from the answer of Lukasz Derylo you can also try:

set.seed(1234)
listA<-data.frame(matrix(rnorm(32), c(8,4)))
listB<-data.frame(matrix(rnorm(32), c(8,4)))
do.call(cbind, Map(function(x, y) sapply(1:5, function(z) cor(x[z:(z+3)], y[z:(z+3)])), listA, listB))
             X1         X2         X3         X4
[1,] -0.2193800  0.3119567 0.31504929  0.7475560
[2,] -0.2669925 -0.4210403 0.43135275  0.9510322
[3,] -0.5657515 -0.6421284 0.82403697  0.2723139
[4,] -0.3829411 -0.6975032 0.09799502 -0.1750354
[5,] -0.8950722 -0.2397563 0.49121024 -0.5240474

Upvotes: 1

Related Questions