xts时间序列的rbind错误是错误还是功能

Is rbind error of xts time series a bug or a feature

我有两个每小时 xts 时间序列,我使用 apply.daily 将其子集化为每日周期。在同一个调用中,我 select/subset 一列形成了数据。当我将两个每日时间序列与 rbind 组合时,我收到一个错误。

我已经找到了解决方案,但我很好奇这种行为是否符合预期。

这里有一些代码可以重现 R 版本 3.5.2 (Linux Debian) 和 xts_0.11-2:

中的错误
data1 <- xts(matrix(1:144, ncol = 2), as.POSIXct("2019-05-09 00:00:00") -
          seq.int(60*60, by = 60*60, length.out = 72))
data2 <- xts(matrix(1:144, ncol = 2), as.POSIXct("2019-05-05 00:00:00") -
          seq.int(60*60, by = 60*60, length.out = 72))

colnames(data1) <- c("col1", "col2")
colnames(data2) <- c("col1", "col2")

data1.daily <- apply.daily(data1[,"col1"], colSums)
data2.daily <- apply.daily(data2[,"col1"], colSums)

data.daily <- rbind(data1.daily, data2.daily)

导致以下错误:

Error in rbind(deparse.level, ...) : length of 'dimnames' [1]
 not equal to array extent

罪魁祸首是第一条属性线 chr [1:3] "col1" "col1" "col1",我觉得它很奇怪:

str(data1.daily)

An ‘xts’ object on 2019-05-06 23:00:00/2019-05-08 23:00:00 containing:
  Data: num [1:3, 1] 1452 876 300
 - attr(*, "dimnames")=List of 2
  ..$ : chr [1:3] "col1" "col1" "col1"
  ..$ : chr "col1"
  Indexed by objects of class: [POSIXct,POSIXt] TZ: 
  xts Attributes:  
 NULL

我可以通过逆向步骤轻松解决问题:

data <- rbind(data1, data2)
data.daily <- apply.daily(data[,"col1"], colSums)

但我更愿意存储频率较低的数据。

所以问题不是如何解决问题,而是这是否可能是一个错误或出于其他目的的某些子设置功能。

您可以为此编写一个函数。不过,我不确定您是否需要 data.frame 或其他格式的数据。无论如何,我会提供前者,因为它是一个相当大的挑战。

res <- do.call(rbind, lapply(list(data1.daily, data2.daily), function(x) {
  t <- as.POSIXct(attr(x, "index"), 
                  origin="1970-01-01")
  value <- as.numeric(x$col1)
  return(data.frame(t, value))
}))
res
#                     t value
# 1 2019-05-06 23:00:00  1452
# 2 2019-05-07 23:00:00   876
# 3 2019-05-08 23:00:00   300
# 4 2019-05-02 23:00:00  1452
# 5 2019-05-03 23:00:00   876
# 6 2019-05-04 23:00:00   300

class(res)
# [1] "data.frame"

我不完全确定发生了什么,但从第一个 xts 对象中删除行名似乎可以解决问题。

rownames(data1.daily) <- NULL
rbind(data1.daily, data2.daily)
#                     col1
# 2019-05-02 23:00:00 1452
# 2019-05-03 23:00:00  876
# 2019-05-04 23:00:00  300
# 2019-05-06 23:00:00 1452
# 2019-05-07 23:00:00  876
# 2019-05-08 23:00:00  300

没错。在 apply.daily().

中使用 sum(),而不是 colSums()
data1.daily <- apply.daily(data1[,"col1"], sum)
data2.daily <- apply.daily(data2[,"col1"], sum)
rbind(data1.daily, data2.daily)
#                     col1
# 2019-05-02 23:00:00 1452
# 2019-05-03 23:00:00  876
# 2019-05-04 23:00:00  300
# 2019-05-06 23:00:00 1452
# 2019-05-07 23:00:00  876
# 2019-05-08 23:00:00  300

错误似乎发生在 apply.daily(或者实际上是 period.apply()), 当底层 sapply() 调用 returns 命名向量时。这些名称后来以行名称结束。我不会将此称为错误,因为在此设置中使用 colSums() 没有多大意义。不过,如果需要的话,让函数对这样的错误更有弹性应该很容易,但这取决于 Joshua。