15

我希望以任意精度对 R 中的日期进行分组。

使用例如lubridate

library(lubridate)
nearest_hour = floor_date(now(), 'hour')

summarise ddply然后,您可以使用简单的 from对此类日期的列表进行分组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上有对此类事情的讨论,但在切割日期之外,似乎没有有任何决议。

4

4 回答 4

8

有点晚了,我没有代表发表评论,但正如 Selva 提到的,lubridate 现在有这个功能:

library(lubridate)
round_date(now(), '3 hours')
floor_date(now(), '3 hours')
ceiling_date(now(), '3 hours')
于 2017-11-10T16:22:20.627 回答
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. 当然,此函数仅适用于以分钟为单位的精度,但您可以轻松地将其扩展到其他单位,甚至在您确实需要时创建一个通用函数。

于 2013-09-25T06:58:30.703 回答
5

润滑已经到达最近的原子单元。要获得最近的 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
}
于 2014-04-19T03:06:05.730 回答
5

lubridate现在有了更通用的round_date()功能。

lubridate::round_date(date, "5 mins")
lubridate::round_date(date, "2 hours")
于 2017-07-13T16:19:57.070 回答