Rounding duration or period to full minutes with lubridate

Viewed 548

Does anybody have a neater way of rounding lubridate period and duration objects to minutes instead of seconds.

For example, I have the following pipe of code:

seconds(x = 3600115) %>% as.duration() %>%  as.period()

This results in: 41d 16H 1M 55S. I would like to round it so it becomes: 41d 16H 2M 0S.

Is anybody aware of a better way than:

(seconds(x = 3600115) / 60) %>% as.numeric() %>% round() %>% dminutes() %>% as.period()

This results in: 41d 16H 2M 0S

2 Answers

A duration object is stored numerically as the number of seconds and period objects can conveniently be converted into seconds using period_to_seconds() so you could use a simple function for this:

library(lubridate)

# Create period object
p <- seconds_to_period(3600115)

# Create duration object
d <- as.duration(p)

minround <- function(x) {
  stopifnot(is.period(x) || is.duration(x))
  if (is.duration(x))
    round(x / 60) * 60
  else
    seconds_to_period(round(period_to_seconds(x) / 60) * 60)
}

minround(p)
# [1] "41d 16H 2M 0S"

minround(d)
# [1] "3600120s (~5.95 weeks)"

A base R option :

as.POSIXct(3600115 - 86400, origin = '1970-01-01', tz = 'UTC') %>%
  round('mins') %>%
  format('%jd %HH %MM 0S')

#[1] "041d 16H 02M 0S"

Few things to note -

  • Used pipe for readability.
  • Output is a string object and not period object.
Related