2017-01-04 8 views
2

У меня есть xts ежегодных данных. Я пытаюсь получить соотношение рангов между каждым годом. Например, это подмножество моих XTS:Как рассчитать скользящую корреляцию между строками в xts?

> yearlyRanks[16:20,45:55] 
      35881 35880 42261 33445 46087 31486 8981 7687 8203 8202 41383 
2009-12-31  8  9 19  8 18 18 16 4 16 16 20 
2010-12-31  4  3 20  6 19  2 17 17 17 17 21 
2011-12-31  3  4 21  3 20  1 18 18 18 18 22 
2012-12-31  6  6 22  5 21 19 19 19 19 19  4 
2013-12-31  7  7  3  4 22 20 20 20 20 20  2 

Я хотел бы знать, соотношение между рядами в каждый год с предыдущим годом. (Попытка рассказать, как хорошо ранг в этом году было предсказано в прошлом году.)

Я пытаюсь использовать это:

yearlyCors <- rollapplyr(coredata(yearlyRanks), width = 2, function(x) cor(x[1], x[2], use = 'n')) 

Но это берет НАВСЕГДА, и это не похоже на работу. Я думаю, что это потому, что я передаю ему набор из двух строк, поэтому он хочет вернуть 2 значения, но я ожидаю только 1. (Это имеет смысл?)

Любые идеи о том, как я буду это делать?

EDIT:

Просто чтобы быть ясно, это то, что я хотел бы от этого подмножества:

> test <- yearlyRanks[16:20,45:55] 
> c(cor(test[1,], test[2,]), cor(test[2,], test[3,]), cor(test[3,], test[4,]), cor(test[4,], test[5,])) 
[1] 0.4679246 0.9930253 0.4854528 0.7193598 

EDIT:

То, что я хочу, это диаг() + 1 из корреляционная матрица. Вот корреляционная матрица (из транспонированной):

> cor(t(test)) 
      2009-12-31 2010-12-31 2011-12-31 2012-12-31 2013-12-31 
2009-12-31 1.00000000 *0.4679246* 0.4716995 0.3722922 0.08786426 
2010-12-31 0.46792463 1.0000000 *0.9930253* 0.4654688 0.17192856 
2011-12-31 0.47169948 0.9930253 1.0000000 *0.4854528* 0.20237689 
2012-12-31 0.37229225 0.4654688 0.4854528 1.0000000 *0.71935975* 
2013-12-31 0.08786426 0.1719286 0.2023769 0.7193598 1.00000000 

Вы можете увидеть Помеченные значения являются те, которые я хочу. Есть ли способ получить доступ к diag + 1 (если вы следуете)?

ответ

3

Это один из способов вы можете получить желаемый результат:

data <- "35881 35880 42261 33445 46087 31486 8981 7687 8203 8202 41383 
2009-12-31  8  9 19  8 18 18 16 4 16 16 20 
2010-12-31  4  3 20  6 19  2 17 17 17 17 21 
2011-12-31  3  4 21  3 20  1 18 18 18 18 22 
2012-12-31  6  6 22  5 21 19 19 19 19 19  4 
2013-12-31  7  7  3  4 22 20 20 20 20 20  2" 
dat <- read.table(text = data) 
yearlyRanks <- xts(dat, order.by = as.POSIXct(row.names(dat))) 

m_yearlyRanks <- t(coredata(yearlyRanks)) 
unlist(lapply(1:(NCOL(m_yearlyRanks) -1), function(i, x) cor(x[,i], x[, i + 1]), x = m_yearlyRanks)) 
# > unlist(lapply(1:(NCOL(m_yearlyRanks) -1), function(i, x) cor(x[,i], x[, i + 1]), x = m_yearlyRanks)) 
# [1] 0.4679246 0.9930253 0.4854528 0.7193598 

Эта последняя строка кода может быть немного сложной для чтения. Это может быть выражено более пространно, как (результат идентичен):

res <- vector("numeric", length = NCOL(m_yearlyRanks) -1) 
for (i in 1:(NCOL(m_yearlyRanks) -1)) { 
    res[i] <- cor(m_yearlyRanks[,i], m_yearlyRanks[, i + 1]) 
} 
# > res 
# [1] 0.4679246 0.9930253 0.4854528 0.7193598 

Ваша ошибка в этом коде:

yearlyCors <- rollapplyr(coredata(yearlyRanks), width = 2, function(x) cor(x[1], x[2], use = 'n')) 

возникает из x возвращения одного столбца данных (числовой вектор), к которой х [1] и x [2] являются элементами 1 и 2 x, которые затем передаются в cor. cor ожидает два вектора данных, но каждый раз, когда вызывается функция roll, он получает 2 скаляра. Попробуйте отладить функцию с помощью browser, и вам станет сразу же очевидно, в чем проблема. напримерпопробуйте позвонить:

yearlyCors <- rollapplyr(coredata(GS), width = 20, function(x) { 
    browser() 
    cor(x[1], x[2], use = 'n') 
    } 
    ) 
1

Я думаю, что понял. Я просто взял первый столбец от корреляционной матрицы транспонирования, а затем взял DIAG:

> test <- yearlyRanks[16:20,45:55] 
> tester <- cor(t(test), use = 'p') 
> tester 
      2009-12-31 2010-12-31 2011-12-31 2012-12-31 2013-12-31 
2009-12-31 1.0000000 0.6309825 0.6167215 0.7106686 0.6076932 
2010-12-31 0.6309825 1.0000000 0.9799418 0.4088352 0.2449624 
2011-12-31 0.6167215 0.9799418 1.0000000 0.3973902 0.2471984 
2012-12-31 0.7106686 0.4088352 0.3973902 1.0000000 0.7315524 
2013-12-31 0.6076932 0.2449624 0.2471984 0.7315524 1.0000000 
> xts(diag(tester[,-1]), order.by = as.Date(rownames(test))[-1]) 
       [,1] 
2010-12-31 0.6309825 
2011-12-31 0.9799418 
2012-12-31 0.3973902 
2013-12-31 0.7315524 

Однако, я не считаю, что это мочалка способ сделать это, как это кажется, что это может оказаться неэффективным , Я вычисляю BUNCH корреляций, которые мне не нужны. Это довольно быстро, но если кто-то хочет опубликовать более эффективное решение, сделайте это!

(Извинения значение изменилось, я не сделал что-то не так и раньше, но не беспокоить Вы все должны получить суть.!)

4

Использование by.column=FALSE и убедитесь, что функция относится к строкам:

cor2 <- function(x) cor(x[1,], x[2,]) 
rollapplyr(coredata(yearlyRanks), 2, cor2, by.column = FALSE) 
## [1] 0.4679246 0.9930253 0.4854528 0.7193598 

Мы также могли бы сделать это:

z <- rollapplyr(as.zoo(yearlyRanks), 2, cor2, by.column = FALSE) 
as.xts(z) 

даяние:

   [,1] 
2010-12-31 0.4679246 
2011-12-31 0.9930253 
2012-12-31 0.4854528 
2013-12-31 0.7193598 
+0

Использование «rollapply» - thx для совместного использования – FXQuantTrader