2017-01-04 2 views
2

Ich habe eine xts der jährlichen Daten. Ich versuche, die Rangkorrelation zwischen jedem Jahr zu erhalten. Zum Beispiel ist dies eine Teilmenge meiner xts:Wie berechnet man die rollende Korrelation zwischen Zeilen in einem 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 

Ich mag würde die Korrelation zwischen den Reihen in jedem Jahr mit dem Vorjahr kennen. (Der Versuch, zu sagen, wie gut diese Rangposition dieses Jahr von der letztjährigen vorhergesagt wurde.)

Ich versuche, diese zu nutzen:

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

Aber es dauert ewig, und es scheint nicht zu funktionieren. Ich denke, es ist, weil ich es eine Reihe von 2 Zeilen übergeben, so will es 2 Werte zurückgeben, aber ich erwarte nur 1. (Ist das sinnvoll?)

Irgendwelche Ideen, wie ich das tun würde?

EDIT:

Nur klar sein, das ist, was ich von dieser Teilmenge wünschen würde:

> 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:

Was ich will, ist die diag() + 1 der Korrelationsmatrix. Hier ist die Korrelationsmatrix (der transponieren):

> 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 

Sie können die Sterne-Werte zu sehen sind die, die ich will. Gibt es eine Möglichkeit, auf diag + 1 zuzugreifen (wenn Sie folgen)?

Antwort

3

Dies ist eine Möglichkeit, Sie das gewünschte Ergebnis erhalten könnte:

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 

Die letzte Zeile des Codes könnte ein bisschen schwierig zu lesen sein. Es könnte mehr verbosely ausgedrückt (das Ergebnis identisch ist):

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 

Ihre Fehler in diesem Code:

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

entsteht aus x eine Spalte von Daten (ein numerischer Vektor) Zurückkehren zu der x [1] und x [2] sind Elemente 1 und 2 von x, die dann an cor übergeben werden. cor erwartet zwei Datenvektoren, erhält aber jedes Mal, wenn die Roll-Funktion aufgerufen wird, zwei Skalare. Versuchen Sie, die Funktion mit browser zu debuggen und es wird Ihnen sofort klar, was das Problem ist. z.B.versuchen Aufruf:

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

Ich denke, ich habe es herausgefunden. Ich habe gerade die erste Spalte aus der Korrelationsmatrix des transponiert, und nahm dann die 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 

Aber ich glaube nicht, dass dies der Bast Weg, dies zu tun, wie es scheint, wie es ineffizient sein könnte . Ich berechne eine Menge Korrelationen, die ich nicht brauche. Es ist viel schnell, aber wenn jemand eine effizientere Lösung veröffentlichen möchte, bitte tun!

(Entschuldigt die Werte verändert hatte ich vor etwas falsch gemacht, aber nicht die Mühe, Sie alle das Wesentliche erhalten sollten.!)

4

Verwendung by.column=FALSE und sicher sein, die Funktion auf die Zeilen bezieht:

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 

könnten wir auch tun:

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

geben:

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

Slick Verwendung von 'rollapply' - thx zum Teilen – FXQuantTrader

Verwandte Themen