将带有 POSIXct 的 ts-object 转换为 zoo-object

Convert ts-object with POSIXct to zoo-object

R 中的短代码

aaaa<-ts(rnorm(5), start = as.POSIXct("2022-04-05 04:28:59",tz="UTC"), freq = 1/60)
index(aaaa)

结果是(这是从“1970-01-01”开始的秒数。它是正确的)

[1] 1649132939 1649132999 1649133059 1649133119 1649133179

现在我将这个 ts-object aaaa 转换为 zoo 对象

as.zoo(aaaa)

结果是

1649132880(1) 1649132940(1) 1649133000(1) 1649133060(1) 1649133120(1) 
...

为什么要更改时间码?在 ts 对象 1649132939,但在 zoo 1649132880

TL;DR: 已在 zoo 版本 1.8-10 中修复,已从 R-Forge and soon from CRAN.

中提供

详细信息: as.zoo() 在内部调用 zooreg(),它试图以 1/frequency 的倍数创建规则时间网格。具体来说,这会检查时间索引是否足够接近 1/frequency 的整数倍。在这里,这个数量

R> all.equal(1649132939 * 1/60, round(1649132939 * 1/60))
[1] TRUE

因此,zooreg() 决定自纪元以来的整数分钟数,并将其四舍五入为 27,485,548.00 分钟,对应于以下秒数:

R> floor(1649132939 * 1/60) * 60
[1] 1649132880

显然,这不是这里的意图。原因是秒数太大,all.equal()中的约定公差不够严格

修复: 现在使用 all.equal(..., tolerance = ts.eps^2),其中 ts.eps 是已经用于确定 frequencydeltat 是一个整数。新的默认值对您的应用程序来说已经足够严格了。

x <- ts((1:5)^2, start = as.POSIXct("2022-04-05 04:28:59", tz = "UTC"), freq = 1/60)
z <- as.zoo(x)
z
## 1649132939(1) 1649132999(1) 1649133059(1) 1649133119(1) 1649133179(1) 
##             1             4             9            16            25 

如果不够严格ts.eps = ...可以设置更严格的公差。