使用 POSIXct 将 ts-object 转换为 Zoo-object

发布于 2025-01-21 02:44:29 字数 506 浏览 3 评论 0原文

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 中,但在动物园 1649132880 中

Short code in R

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

result is (this is number of seconds from "1970-01-01". It's correct)

[1] 1649132939 1649132999 1649133059 1649133119 1649133179

Now I convert this ts-object aaaa to zoo object

as.zoo(aaaa)

result is

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

Why timecode is changed? In ts object 1649132939, but in zoo 1649132880

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

浮云落日 2025-01-28 02:44:29

TL;DR:已在 zoo 版本 1.8-10 中修复,已可从 R-Forge 很快就会来自 CRAN

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

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 是一个容差,已用于确定频率或增量之一是否为整数。新的默认值对于您的应用程序来说足够严格。

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 = ... 可以设置为更严格的容差。

TL;DR: Fixed in zoo version 1.8-10, already available from R-Forge and soon from CRAN.

Details: as.zoo() calls zooreg() internally which tries to create a regular time grid in multiples of 1/frequency. Specifically, this checks whether the time index is sufficiently close to integer multiples of 1/frequency. Here, this amounts

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

Hence, zooreg() decided that an integer number of minutes since the epoch is intended and rounds it to 27,485,548.00 minutes which corresponds to the following number of seconds:

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

Clearly, this is not intended here. The reason is that the number of seconds is so large that the conventional tolerance in all.equal() is not strict enough.

Fix: Now all.equal(..., tolerance = ts.eps^2) is used where ts.eps is a tolerance that is already used for determining whether one of frequency or deltat is an integer. The new default is strict enough for your application.

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 

And if it is not strict enough ts.eps = ... can be set to an even stricter tolerance.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文