如何计算 xts 中行之间的滚动相关性?
How to calculate rolling correlation between rows in an 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 行,所以它想要 return 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(如果你遵循)?
我想我明白了。我只是从转置的相关矩阵中取出第一列,然后进行诊断:
> 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
但是,我认为这不是最好的方法,因为它看起来效率很低。我正在计算一堆我不需要的相关性。它非常快,但是如果有人想要 post 更有效的解决方案,请做!
(抱歉,值已更改。我之前做错了,但不用担心!你们都应该明白要点!)
这是您获得所需结果的一种方式:
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,然后将其传递到 cor
. cor
需要两个数据向量,但每次调用 roll 函数时它都会获得 2 个标量。尝试使用 browser
调试该函数,您会立即清楚问题所在。例如试试打电话:
yearlyCors <- rollapplyr(coredata(GS), width = 20, function(x) {
browser()
cor(x[1], x[2], use = 'n')
}
)
使用 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
我有 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 行,所以它想要 return 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(如果你遵循)?
我想我明白了。我只是从转置的相关矩阵中取出第一列,然后进行诊断:
> 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
但是,我认为这不是最好的方法,因为它看起来效率很低。我正在计算一堆我不需要的相关性。它非常快,但是如果有人想要 post 更有效的解决方案,请做!
(抱歉,值已更改。我之前做错了,但不用担心!你们都应该明白要点!)
这是您获得所需结果的一种方式:
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,然后将其传递到 cor
. cor
需要两个数据向量,但每次调用 roll 函数时它都会获得 2 个标量。尝试使用 browser
调试该函数,您会立即清楚问题所在。例如试试打电话:
yearlyCors <- rollapplyr(coredata(GS), width = 20, function(x) {
browser()
cor(x[1], x[2], use = 'n')
}
)
使用 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