Скользящая корреляция между списками в R

У меня есть два списка, listA и listB, которые я хотел бы рассчитать корреляцию между ними, используя скользящее окно размера 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

В частности, я хочу рассчитать cor(listA[1:4,1],listB[1:4,1]), используя скользящее окно размера 4, что означает, что у меня будет 5 значений для корреляции между listA и listB для столбца A. Как только это будет сделано для столбца A, я хотел бы сделать то же самое для столбца B , С и Д.

Раньше я добивался этого с помощью «rollapplyr», но объект, над которым я работал, был объектом XTS, а не двумя отдельными объектами, которые моему простому маленькому мозгу облегчили понимание.

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

Может ли кто-нибудь предложить способ сделать это между двумя списками?


person TheGoat    schedule 07.06.2017    source источник
comment
Можете ли вы сделать listA и listB воспроизводимыми, пожалуйста? Это фреймы данных?   -  person Sotos    schedule 07.06.2017


Ответы (2)


Используя данные из ответа Лукаша Дерило, вы также можете попробовать:

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
person Roman    schedule 07.06.2017

Позвольте мне случайным образом сгенерировать listA и listB и работать с ними:

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

Затем подготовьте массив для ваших результатов:

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

Цикл в цикле сейчас:

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

Вот что я получил:

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

То же самое можно было бы сделать без циклов, используя вместо этого семейство apply.

person Łukasz Deryło    schedule 07.06.2017
comment
вы всегда можете добавить set.seed() в начало скрипта при обработке псевдослучайных чисел (таких как rnorm), чтобы получить воспроизводимые результаты - person amonk; 07.06.2017
comment
Спасибо, Лукаш. Могу я спросить, как можно добиться того же с помощью применения, требуется ли вложенное приложение? - person TheGoat; 08.06.2017
comment
Посмотрите на ответ Джимбо. Он содержит хорошее сочетание do.call-sapply :) - person Łukasz Deryło; 08.06.2017