creating a time baseline in lubridate

Hello everyone,
I have a variable of time (hms) that represents the time a blood sample was drawn. I would like to make a baseline of midnight (or perhaps 00:05 :slight_smile: ) so that I can make an analysis of changes in cellular composition from midnight to blood draw. I sense I need to make an interval, but I don't know how to proceed since the baseline for each sample will have different dates, although the same baseline time. Time can be set up as number of minutes since midnight.
Any ideas would be much appreciated.

Some of these functions may help you:

The base case, with individually entered times

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
basetime <- ymd_hms("2010-12-13 00:00:00")
drawtime <- ymd_hms("2010-12-13 15:30:30")
elapsed  <- drawtime - basetime
elapsed
#> Time difference of 15.50833 hours

Created on 2020-09-09 by the reprex package (v0.3.0)

Because lubridate provides functions to access date components, the elapsed variable can be through hour() and minute().

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
basetime <- ymd_hms("2010-12-13 00:00:00")
drawtime <- ymd_hms("2010-12-13 15:30:30")
elapsed  <- drawtime - basetime

(hour(drawtime)*60 + minute(drawtime)) / 60
#> [1] 15.5

Created on 2020-09-09 by the reprex package (v0.3.0)


<sup>Created on 2020-09-09 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>

Thank you technocrat for your suggested solution. The dataset I received had already separated the date from time, so I have two columns. They are formatted in "hms".

Martin,
I do have the time variable formatted in hms:Pretty Time of Day. I can confirm that the class is hms diff time. I was wondering if I could remove the seconds, so the time would represent the number of minutes since 00:00 ? I have a problem with the large number that represents all those seconds: 1) interpretation of estimates from a linear model, 2) calculation of differential expression. I am hoping that total number of minutes since midnight would be easier to work with.
Thanks for your help.

I think hms requires the seconds to be specified. You can divide the duration by 60 to get the no. of minutes.

Ok, thanks this is what I am thinking. But I need some guidance on how to proceed. If I have a time, for example 09:10:00, how do I convert to a numerical value in order to divide by 60?

I'd use lubridate::time_length().

> t1 <- ymd_hms('2020-09-14 12:00:00')
> t2 <- ymd_hms('2020-09-14 13:00:05')
> dur <- t2 - t1
> dur
Time difference of 1.001389 hours
> class(dur)
[1] "difftime"
> time_length(dur, 'second')
[1] 3605
> time_length(dur, 'minute')
[1] 60.08333
> time_length(dur, 'hour')
[1] 1.001389
> ```
1 Like

Thanks so much. I look forward to trying this solution.

Best regards!

Thanks again for your suggestion. Unfortunately, the colleague before me separated date from time into two different columns. I am wondering if I should put them back together? In order to make a baseline, I made another column with the baseline hour as 07:00:00. This is formatted as a character string. I tried to reformat as hms but did not manage it. Do you have another suggestion I could try?

If you still have the original timestamps (date-times), then I'd use those instead of the separate date and time columns. You can create your baseline using the ymd_hms function I used in my previous reply.

If you don't have the original timestamps, you're probably still better off putting the dates and times back together. However, figuring the best way to do that will require knowing exactly what column types you have. Any possibility you could post a portion of your data by running dput(head(<name of your dataframe>)) and posting the result here?

Finally, don't give up. Working with dates and times is super annoying whether it's Excel, R, or SQL. But if the alternative is to do the calculations by hand, then the effort is worth it.

I am on a secure server so am not able to copy and paste code, but I can try to give you an update. I do not have the original timestamps, unfortunately. So I made a second variable called "Baseline" and converted the character string of 07:00:00 with library(hms). The I used dplyr,
timeDiff <- df %>% group_by(subj_ID) %>% arrange(Baseline, Blood_draw_time)%>% mutate(timeChange = Blood_draw_time - Baseline) %>% ungroup(). Now my timeChange variable is in seconds so I tried samples$timeChange <- as.number(samples$timeChange, units = "mins"). My supervisor asked me to round to the nearest hour, so perhaps I will round the Blood_draw_time beforehand. Anyway, my method is probably the hardest route to take, but I am hacking away at it. As you say, working with dates and time is a challenge! Thank for your input.

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.