我希望将R中的日期分组为任意精度。
使用例如最近的小时或分钟进行此操作是非常简单的。 lubridate
:
library(lubridate)
nearest_hour = floor_date(now(), 'hour')
然后,您可以将此类日期的列表分组,例如来自summarise
的简单ddply
plyr
。
我想做的是以任意精度的圆形日期,例如:到最近的15分钟或每3小时:
nearest_three_hours = floor_date(now(), '3 hours')
在http://r.789695.n4.nabble.com/Truncating-dates-and-other-date-time-manipulations-td866901.html讨论了这些事情,但在截止日期之外,似乎没有任何解决方案。
任何帮助表示赞赏!谢谢。
答案 0 :(得分:5)
您可以尝试此操作,仍然基于lubridate
库
library(lubridate)
round_minute<-function(x,precision){
m<-minute(x)+second(x)/60
m.r<- round(m/precision)*precision
minute(x)<-m.r
second(x)<-0
x
}
round_minute(ymd_hms(c("2013-06-03 22:53:00","2013-05-03 12:18:00","2013-05-03 00:10:00")),15)
> "2013-06-03 23:00:00 UTC" "2013-05-03 12:15:00 UTC" "2013-05-03 00:15:00 UTC"
由于lubridate
,代码处理了所有棘手的情况。当然,此功能仅适用于以分钟表示的精度,但您可以轻松地将其扩展到其他单位,如果您确实需要,甚至可以创建一个通用函数。
答案 1 :(得分:5)
lubridate已经到最近的原子单位。为了达到最接近的15分钟,我认为这是你想要做的事情(不是圆形),你只需要通过findInterval和一组定义的断点映射到正确的范围。试试这个floor_time,它在功能上等同于floor_date,但允许你指定一个变量#of units,包括秒,分钟或小时。
floor_time <- function(x, k = 1, unit = c("second", "minute", "hour", "day",
"week", "month", "year")) {
require(lubridate)
nmax <- NULL
switch(unit, second = {nmax <- 60},
minute = {nmax <- 60},
hour = {nmax <- 24})
cuts <- seq(from = 0, to = nmax - 1, by = k)
new <- switch(unit,
second = update(x, seconds = cuts[findInterval(second(x), cuts)]),
minute = update(x, minutes = cuts[findInterval(minute(x), cuts)],
seconds = 0),
hour = update(x, hours = cuts[findInterval(hour(x), cuts)],
minutes = 0, seconds = 0),
day = update(x, hours = 0, minutes = 0, seconds = 0),
week = update(x, wdays = 1, hours = 0, minutes = 0, seconds = 0),
month = update(x, mdays = 1, hours = 0, minutes = 0, seconds = 0),
year = update(x, ydays = 1, hours = 0, minutes = 0, seconds = 0))
new
}
答案 2 :(得分:3)
lubridate
现在有一个更通用的round_date()
函数。
lubridate::round_date(date, "5 mins")
lubridate::round_date(date, "2 hours")
答案 3 :(得分:3)
有点晚了,我没有代表发表评论,但正如Selva所说,lubridate现在有这个功能:
library(lubridate)
round_date(now(), '3 hours')
floor_date(now(), '3 hours')
ceiling_date(now(), '3 hours')