如何计算xts中行之间的滚动相关性?

时间:2017-01-04 14:24:30

标签: r correlation 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行,所以它想要返回2个值,但我只期望1.(这有意义吗?)

关于如何做到这一点的任何想法?

编辑:

为了清楚起见,这是我想要的那个子集:

> 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

编辑:

我想要的是相关矩阵的diag()+ 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 个答案:

答案 0 :(得分: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

答案 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返回一列数据(数字向量),x [1]和x [2]是x的元素1和2,然后传递到corcor期待两个数据向量,但每次调用roll函数时它会得到2个标量。尝试使用browser调试该功能,它将立即变得明显,问题是什么。例如试着打电话:

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

答案 2 :(得分:1)

我想我明白了。我只是将第一列从转置的相关矩阵中取出,然后进行了诊断:

> 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相关性。这很快,但如果有人想发布更有效的解决方案,请做!

(道歉,价值观发生了变化。我以前做错了什么,但没有麻烦!你们都应该得到主旨!)