我有两个小时的xts时间序列,我将它们与apply.daily
的每日周期子集化。在同一调用中,我选择/细分一列以形成数据。当我将两个每日时间序列与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)
但是我希望在频率较低时存储数据。
所以问题不在于如何解决问题,而是这可能是错误还是出于其他目的的子设置功能。</ p>
答案 0 :(得分:2)
我不确定是怎么回事,但是从第一个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
对。使用sum()
中的colSums()
,而不是apply.daily()
中的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()
)中,
当底层的colSums()
调用返回一个命名向量时。这些名称后来以行名结尾。我不会将其称为错误,因为在此设置中使用from PyQt5.QPrintSupport import QPrinter
并没有多大意义。但是,要使函数对这样的错误更具弹性,应该很容易,如果需要的话,但这取决于约书亚。
答案 1 :(得分:0)
您可以为此目的编写一个函数。不过,我不确定是否需要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"