0

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?

1
  • Can you make listA and listB reproducible please? Are they data frames? Commented Jun 7, 2017 at 7:40

2 Answers 2

1

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 
Sign up to request clarification or add additional context in comments.

Comments

1

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.

3 Comments

you can always add set.seed() in the beginning of the script, when treating with pseudorandom numbers (such as rnorm) in order to get reproducible results
Thanks Lukasz, Can I ask how can the same be achieved with an apply, is it a nested apply that's needed?
Look at Jimbou's answer. It contains nice do.call-sapply combo :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.