使用基本的R功能将POSIX日期(POSIXct)舍入

39

我目前在为一个软件包处理日期和时间方面进行很多尝试。

偶然看到这个帖子让我再次想起在转向使用贡献包之前,通常检查一下是否可以使用基本的 R 功能来完成任务是不错的选择。

那么,是否可能使用基本的 R 功能来四舍五入一个类型为POSIXct的日期呢?

我已经检查过了。

methods(round)

这里的"only"只是给了我

[1] round.Date      round.timeDate*

   Non-visible functions are asterisked

这是我想要做的事情(伪代码)

x <- as.POSIXct(Sys.time())
[1] "2012-07-04 10:33:55 CEST"

round(x, atom="minute")
[1] "2012-07-04 10:34:00 CEST"

round(x, atom="hour")
[1] "2012-07-04 11:00:00 CEST"

round(x, atom="day")
[1] "2012-07-04 CEST"

我知道可以使用 timeDatelubridate 等方式实现,但是我想尽量减少包依赖。所以在查看各自软件包的源代码之前,我想问一下是否已经有人做过这样的事情。

3个回答

51

baseround.POSIXt 来实现这个功能。不确定为什么它没有涉及到 methods

x <- as.POSIXct(Sys.time())
x
[1] "2012-07-04 10:01:08 BST"
round(x,"mins")
[1] "2012-07-04 10:01:00 BST"
round(x,"hours")
[1] "2012-07-04 10:00:00 BST"
round(x,"days")
[1] "2012-07-04"

这个函数很棒,但奇怪的是它没有周、月或年的四舍五入;对于我的情况,我将采用@nzcoops的答案。 - chepyle
5
此外,round函数会将POSIXct类型转换为POSIXlt类型——有时可能会引起问题。 - Pere
1
...可以通过将输出包装在as.POSIXct()中解决,如果需要的话。 - fdetsch
非常有帮助和简单的解决方案 - hachiko

20

在这个主题上,使用lubridate,还可以了解一下ceiling_date()floor_date()函数:

x <- as.POSIXct("2009-08-03 12:01:59.23")
ceiling_date(x, "second")
# "2009-08-03 12:02:00 CDT"
ceiling_date(x, "hour")
# "2009-08-03 13:00:00 CDT"
ceiling_date(x, "day")
# "2009-08-04 CDT"
ceiling_date(x, "week")
# "2009-08-09 CDT"
ceiling_date(x, "month")
# "2009-09-01 CDT"

2
我希望 POSIXct 可以提供月份舍入功能,因为 floor_date 太慢了。 - Alex A.
这个问题明确指出“我知道可以用timeDate、lubridate等包来完成,但我想保持包的依赖性较低。” - Simon C.

1
如果您不想调用外部库并像我一样保留POSIXct,那么这是一个想法(受this question的启发):使用strptime并粘贴一个虚假的月份和日期。如this comment中所说,应该可以更直接地执行它。

"对于strptime,输入字符串不需要完全指定日期: 假定未指定的秒、分或小时为零, 未指定的年、月或日为当前年、月或日。"

因此,似乎您必须使用strftime输出截断的字符串,粘贴缺失的部分并再次转换为POSIXct。
以下是更新答案的方式:
x <- as.POSIXct(Sys.time())
x
[1] "2018-12-27 10:58:51 CET"
round(x,"mins")
[1] "2018-12-27 10:59:00 CET"
round(x,"hours")
[1] "2018-12-27 11:00:00 CET"
round(x,"days")
[1] "2018-12-27 CET"
as.POSIXct(paste0(strftime(x,format="%Y-%m"),"-01"))     #trunc by month
[1] "2018-12-01 CET"
as.POSIXct(paste0(strftime(x,format="%Y"),"-01-01"))     #trunc by year
[1] "2018-01-01 CET"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接