【问题标题】:How to calculate rolling correlation between rows in an xts?如何计算 xts 中行之间的滚动相关性?
【发布时间】:2017-05-18 21:10:19
【问题描述】:

我有 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(如果你关注的话)?

【问题讨论】:

    标签: r correlation xts


    【解决方案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
    

    但是,我认为这不是最糟糕的方法,因为它似乎效率低下。我正在计算一堆我不需要的相关性。它很快,但如果有人想发布更有效的解决方案,请这样做!

    (抱歉,价值观发生了变化。我之前做错了什么,但没有麻烦!你们都应该明白要点!)

    【讨论】:

      【解决方案2】:

      这是获得所需结果的一种方式:

      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')
          }
          )
      

      【讨论】:

        【解决方案3】:

        使用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
        

        【讨论】:

          猜你喜欢
          • 2018-11-17
          • 1970-01-01
          • 2014-05-22
          • 1970-01-01
          • 2020-01-21
          • 1970-01-01
          • 2017-05-02
          • 2012-08-14
          • 1970-01-01
          相关资源
          最近更新 更多