简体   繁体   中英

Formatting a duration as HH:mm:ss in R

Forgive me if this is a duplicate question but I can't seem to type the perfect search to get what I need. I would like to convert seconds(as a numeric) into a duration in the format HH:mm:ss.

Below is a data frame with the original value and the expected value.

df <- data.frame(Duration = c(19, 250, 3, 3600), Expected = c("00:00:19", "00:04:10", "00:00:03", "01:00:00"))

This builds a date object with as.POSIXct and adds the duration, then truncates the output to Time with strftime . Resets to 00:00:00 if it counts higher than 24h. For higher numbers see the approach at the bottom.

df
  Duration
1       19
2      250
3        3
4     3600

df$Expected <- strftime(as.POSIXct("00:00:00", format="%H:%M:%S") + 
                        df$Duration, format="%H:%M:%S")

df
  Duration Expected
1       19 00:00:19
2      250 00:04:10
3        3 00:00:03
4     3600 01:00:00

In case you need to count higher than a day use this

df
  Duration
1       19
2      250
3        3
4     3600
5   431170

df$Expected <- paste0(sprintf("%02.f",floor(df$Duration/3600)),":",
                      sprintf("%02.f",(df$Duration/60)%%60),":",
                      sprintf("%02.f",df$Duration%%60))

df
  Duration  Expected
1       19  00:00:19
2      250  00:04:10
3        3  00:00:03
4     3600  01:00:00
5   431170 119:46:10

And another answer using lubridate and hms :

library(lubridate)
library(hms)

df <- data.frame(Duration = c(19, 250, 3, 3600, 86401))
df$Expected <- hms::hms(seconds_to_period(df$Duration))

df
  Duration Expected
1       19 00:00:19
2      250 00:04:10
3        3 00:00:03
4     3600 01:00:00
5    86401 24:00:01

We can consider duration column as seconds since epoch and use format to extract the time component from it.

A base R approach -

format(as.POSIXct(df$Duration, origin = '1970-01-01', tz = 'UTC'), '%T')
#[1] "00:00:19" "00:04:10" "00:00:03" "01:00:00"

I wrote a little function for this:

hms <- function(s) {
  s <- as.integer(s)
  list(s %/% 3600, s %/% 60 %% 60, s %% 60) |> 
    lapply(sprintf, fmt = '%02i') |> 
    c(sep = ':') |> 
    do.call(what = 'paste')
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM