round a date in R to an arbitrary minute/hour level of precision
lubridate
now has a more generic round_date()
function.
lubridate::round_date(date, "5 mins")
lubridate::round_date(date, "2 hours")
lubridate already floors to the nearest atomic unit. To get floor to the nearest 15 minutes, which I think is what you want to do (not round), you just need to map into the correct range via findInterval and a defined set of breakpoints. Try this floor_time, which is functionally equivalent to floor_date, but allows you to specify a variable # of units for seconds, minutes or hours.
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
}
A little late, and I don't have rep to comment, but as Selva mentioned, lubridate now has this functionality:
library(lubridate)
round_date(now(), '3 hours')
floor_date(now(), '3 hours')
ceiling_date(now(), '3 hours')
You can try this, still based on the lubridate
library
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"
The code handle well all the tricky situations thanks to lubridate
. Of course this function works only for precision expressed in minutes but you can easily extend it to other units, and even create a generic function if you really need it.