应用于具有多列的 xts

Apply over xts with multiple columns

我遇到了一个我无法理解的奇怪错误。让我解释一下变量及其含义:

ts <- a xts object
range.matrix <- matrix with two columns and n rows (only knows at execution time)

所以,range.matrix 包含日期范围。第一列是范围的开始,第二列是范围的结束。目标是按 range.matrix 中的范围对 ts 时间序列进行切片,得到一个包含所有切片的列表。

它在某些范围内失败但在其他范围内失败,并且在 1 行矩阵上失败...错误消息是:

Error in array(ans, c(len.a%/%d2, d.ans), if (!is.null(names(dn.ans)) length of 'dimnames' 1 not equal to array extent

用这个玩具示例检查一下自己(range.matrix 包含投射的数字 as.Date)

    library(xts)
    ts <- xts(cbind('a'= c(1,2,3,4,5,6,7,8),'b' =c(1,2,3,4,5,6,7,8),'c'= c(1,2,3,4,5,6,7,8))
            ,order.by = as.Date(as.Date('2017-01-01'):(as.Date('2017-01-01')+7)) )

    range.matrix <- matrix(c(16314,17286), ncol = 2,byrow = TRUE) # Fails. Range: "2014-09-01/2017-04-30"
    range.matrix <- matrix(c(16314,17236,16314,17286), ncol = 2,byrow = TRUE) # Fails. Range: "2014-09-01/2017-03-11" and "2014-09-01/2017-04-30"
    range.matrix <- matrix(c(16314,17236,17237,17286), ncol = 2,byrow = TRUE) # does not fail. "2014-09-01/2017-03-11" and "2017-03-12/2017-04-30"

    apply(range.matrix,
          1,
          function(r) {
          ts[paste0(as.Date(r[1]), '/', as.Date(r[2]))]
          })

有线索吗?与dimnames有关,但找不到解决方案

试试这个,你不会有问题的:

lapply(split(range.matrix, row(range.matrix)), function(x) {
  ts[paste0(as.Date(r[1]), '/', as.Date(r[2]))]})

就我个人而言,我不会按照您想要的方式在 xts 对象上使用 apply(我会按照上面的方式进行;lapply 更自然)。

apply用在数组上,一个xts对象不仅仅是一个矩阵(数组),还支持时间索引等赋予xts强大功能的属性。您可以在 xts 对象上使用类似 coredata 的东西来仅 return 基础矩阵到 apply 调用,然后您不会得到错误,但结果不会太多感觉。

apply(range.matrix,
      1,
      function(r) {
        res <- ts[paste0(as.Date(r[1]), '/', as.Date(r[2]))]
        coredata(res)
      })