为什么 round_date() 对某些单位返回错误?

发布于 2025-01-11 16:49:11 字数 938 浏览 0 评论 0原文

我尝试将日期(POSIXlt 对象)四舍五入到最接近的 5 分钟。我尝试使用 round_date() 函数并遇到以下情况:

> date
[1] "2012-11-01 15:41:00 EET"
> is.POSIXlt(date)
[1] TRUE
> round_date(date, "hour")
[1] "2012-11-01 16:00:00 EET"
> round_date(date, "min")
[1] "2012-11-01 15:41:00 EET"
> round_date(date, "5 mins")
Error in above - mid : non-numeric argument to binary operator

它似乎适用于秒、分钟、小时和天。示例中列出的所有其他单元都会返回此错误。

我遵循了 线程的建议并指定了 tz ,但这并没有改变任何事情。

period() 函数似乎工作正常:

> period("5 mins")
[1] "5M 0S"

上面的示例是为了简单起见,因为该数据是数据帧的一部分。我不知道这是否相关,但我也尝试使用变异和替换来解决它。失败了

必须提供x“来源”

谢谢!

编辑

POSIXlt 对象可以重现该问题。错误报告已提交。我的问题的快速解决方法是:

> round_date(as.POSIXct(date), "5 mins")
[1] "2012-11-01 15:40:00 EET"

I try to round dates (POSIXlt object) to the nearest 5 minutes. I tried to use round_date() function and run into following situation:

> date
[1] "2012-11-01 15:41:00 EET"
> is.POSIXlt(date)
[1] TRUE
> round_date(date, "hour")
[1] "2012-11-01 16:00:00 EET"
> round_date(date, "min")
[1] "2012-11-01 15:41:00 EET"
> round_date(date, "5 mins")
Error in above - mid : non-numeric argument to binary operator

It seems to work for second, minute, hour and day. All the other units listed in the examples return this error.

I followed the advice from this thread and specified tz, but this didn't change anything.

period() function seems to work fine:

> period("5 mins")
[1] "5M 0S"

The above example is for the sake of simplicity as this data is a part of data frame. I don't know if that is relevant, but I also tried to work around it using mutate and replace. That failed with

x 'origin' must be supplied

Thanks!

EDIT

The problem was reproducible for POSIXlt objects. Bug report is submitted. Quick fix for my problem was:

> round_date(as.POSIXct(date), "5 mins")
[1] "2012-11-01 15:40:00 EET"

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

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

发布评论

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

评论(1

﹂绝世的画 2025-01-18 16:49:11

round.POSIXt 函数/方法不支持将数字修饰符放在受支持的时间单位之一之前,至少帮助页面中没有记录。 seq.POSIXtcut.POSIXt 支持这样的功能,因此我当然可以理解为什么这可能是一个合理的假设。您可以通过对相当于 5 分钟的秒进行模除,然后乘以该数量来获得所需的结果,但您当然需要重新转换为 POSIXlt 类。 as.POSIXt.numeric 的问题之一是您确实需要指定一个“起源”,通常是“1970-01-01”。 (在我看来,这应该是一个默认假设。)

艾伦的想法是正确的,我再次对问题的阅读过于仓促。 (如果我看到类似以下内容,可能会有所帮助:

library(lubridate)

[编辑]我的新猜测是,这与夏令时到标准时间的切换有关。我无法通过以下方式复制错误:

x <- lubridate::ymd_hms("2009-08-03 12:01:59.23")
lubridate::round_date(x, "5 mins")
[1] "2009-08-03 12:00:00 UTC"

EET DST -> 标准转换是

东欧时间 (EET),适用于保加利亚、爱沙尼亚、芬兰、希腊、拉脱维亚、罗马尼亚、土耳其、乌克兰等国家。
夏令时从当地时间 03:00 开始,此时时钟向前拨至 04:00。

欧洲的夏令时 (DST) 周期为每年 3 月最后一个星期日的 01:00 UTC(协调世界时)到 10 月最后一个星期日的 01:00 UTC。

[进一步编辑];又错了。现在我可以做出不良行为了。当“ymd_hms”创建的向量转换为 POSIXlt 类时,将时间提前超过 3-4 小时并不能解决问题:

 x <- lubridate::ymd_hms("2012-11-01 15:41:00 EET",tz="EET")
 lubridate::round_date(x, "5 mins")
#[1] "2012-11-01 15:40:00 EET"

x <- lubridate::ymd_hms("2012-11-01 17:41:00 EET",tz="EET")
 lubridate::round_date(as.POSIXlt(x), "5 mins")
#Error in above - mid : non-numeric argument to binary operator

pkg:lubridate 当操作 POSIXlt 对象时?在 POSIXct 对象上操作没有错误:

lubridate::round_date(as.POSIXct(x), "5 mins")
[1] "2012-11-01 17:40:00 EET"

报告 R 包中可疑错误的方法是运行:

maintainer("lubridate")
#[1] "Vitalie Spinu <[email protected]>"

并发送带有 [MCVE] 的报告。

Placing a numeric modifier prior to one of the supported time units is not a supported option for the round.POSIXt function/method, at least it's not documented in the help page. Such a feature is supported for seq.POSIXt and cut.POSIXt, so I can certainly see why that might have been a reasonable assumption. You could get that as a desired result by doing modulo division by the seconds equivalent of 5 mins and then ordinary multiplication by that amount, but you would of course need to reconvert to POSIXlt class. One of the gotcha's of as.POSIXt.numeric is that you do need to specify an "origin" which is typically "1970-01-01". (Seems to me that it ought to be a default assumption.)

Allan is correct in thinking that yet again I've been too hasty im my reading of a question. (It might have helped if I had seen something along the lines of:

library(lubridate)

[EDIT] My new guess is that this is something to do with Daylight-to-Standard Time switchover. I'm unable to replicate the error with:

x <- lubridate::ymd_hms("2009-08-03 12:01:59.23")
lubridate::round_date(x, "5 mins")
[1] "2009-08-03 12:00:00 UTC"

The EET DST-> Standard transition is

Eastern European Time (EET), observed in countries including Bulgaria, Estonia, Finland, Greece, Latvia, Romania, Turkey, Ukraine.
Daylight saving time starts at 03:00 local time, when clocks move forward to 04:00.

The Daylight Saving Time (DST) period in Europe runs from 01:00 UTC (Coordinated Universal Time) on the last Sunday of March to 01:00 UTC on the last Sunday of October every year.

[Further EDIT]; Wrong again. And now I am able to cause the undesirable action. Advancing the hour beyond the 3-4 hour does not cure the problem when a "ymd_hms"-created vector is converted to POSIXlt class:

 x <- lubridate::ymd_hms("2012-11-01 15:41:00 EET",tz="EET")
 lubridate::round_date(x, "5 mins")
#[1] "2012-11-01 15:40:00 EET"

x <- lubridate::ymd_hms("2012-11-01 17:41:00 EET",tz="EET")
 lubridate::round_date(as.POSIXlt(x), "5 mins")
#Error in above - mid : non-numeric argument to binary operator

Could there be a bug in pkg:lubridate when operating on POSIXlt objects? There's no error operating on POSIXct objects:

lubridate::round_date(as.POSIXct(x), "5 mins")
[1] "2012-11-01 17:40:00 EET"

The way to report suspected bugs in R package is to run:

maintainer("lubridate")
#[1] "Vitalie Spinu <[email protected]>"

And send a report with a [MCVE].

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