Home > Back-end >  Convert 24 hour time from Character type to 24 hour time and subtract two times
Convert 24 hour time from Character type to 24 hour time and subtract two times

Time:05-27

I have two columns stored as character data that represent 24-hour time.

Wakeup <- c("0700", "0515", "0815")

Bedtime <- c("2400", "2230", "0100")

I would like to subtract these times and get the desired column below (as numeric).

Hours_slept <- c(7, 6.75, 7.25)

I would like to use the tidyverse.

CodePudding user response:

There's a few interesting things to think through here, such as how to convert to a time object (if that's what you're aiming for) and how to work out time distance without a date (we can tell that 2230 is day before wakeup and 0100 is same day, but R doesn't).

If you want to stick to very tidyversey ways of doing things, then you can make it a tibble and mutate using lubridate functions:

library(tidyverse)
library(lubridate)

Wakeup <- c("0700", "0515", "0815")

Bedtime <- c("2400", "2230", "0100")

tibble(Bedtime, Wakeup) %>%
  mutate(
    # First change makes each a time, formatting time string by inserting space
    across(.fns = ~ str_replace(.x, "(?=\\d{2}$)", " ") %>% hm()),
    # Then time difference
    time_diff = Wakeup - Bedtime,
    # Some are negative - a quick fix may be just to add 24h
    time_diff = if_else(time_diff < 0, hours(24)   time_diff, time_diff),
    # Then convert to decimal number of hours
    time_diff = as.numeric(time_diff) / (60 * 60)
  )

#> # A tibble: 3 × 3
#>   Bedtime    Wakeup    time_diff
#>   <Period>   <Period>      <dbl>
#> 1 24H 0M 0S  7H 0M 0S       7   
#> 2 22H 30M 0S 5H 15M 0S      6.75
#> 3 1H 0M 0S   8H 15M 0S      7.25

Created on 2022-05-26 by the reprex package (v2.0.1)

CodePudding user response:

Here's a base R implementation. Like Andy mentioned, there is an assumption that the Bedtime must be before Wakeup, and by no more than a day:

Wakeup <- c("0700", "0515", "0815")
Bedtime <- c("2400", "2230", "0100")

Wakeup <- as.POSIXct(Wakeup, format='%H%M')
Bedtime <- as.POSIXct(Bedtime, format='%H%M')
Bedtime[Bedtime > Wakeup] <- Bedtime[Bedtime > Wakeup] - as.difftime(1, units='days')
Hours_slept <- as.numeric(difftime(Wakeup, Bedtime, units='hours'))
# [1] 7.00 6.75 7.25

The input hours are converted into datetimes, (which by default will take the current date). Subtract one day from any times where the bed time is greater than the corresponding wakeup. Then subtract the datetimes with difftime and get the data in numeric hours.

  • Related