Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding time to time in R

Tags:

datetime

r

Dates and times are so confusing in R. I just want to randomly generate some 24 hour clock times and then add to them.

The random generation:

library(lubridate)

hourTime <- as.list(format(seq.POSIXt(as.POSIXct(Sys.Date()),
                                    as.POSIXct(Sys.Date()+1),
                                    by = "5 min"),
                         "%H:%M", tz="GMT"))

Trying to convert into a Date:

df$ARRIVALTIME <- replicate(1000, sample(hourTime, 1, replace=F))

Trying to add to the previous time:

df$TRETTIME <- df$ARRIVALTIME +
    (hours(sample(1:3, 1000, replace=T)) + minutes(sample(1:60, 1000, replace=T)))

This fails I guess because I don't have a time formatted object. How can I add random times to the ARRIVALTIME?

like image 746
Sebastian Zeki Avatar asked Dec 17 '22 22:12

Sebastian Zeki


2 Answers

It is simpler -- the underlyng POSIXt is either the long-form / by-element POSIXlt (not useful here) or the compact POSIXct -- which is just a double (aka numeric) -- which which you can do 'Math'.

So create time anyway you want, then just add real values:

R> now <- Sys.time()
R> set.seed(123)
R> deltas <- cumsum(rnorm(5))    # just five N(0,1), added up 
R> 
R> now
[1] "2018-06-14 16:50:36.55687 CDT"
R> 
R> now + deltas
[1] "2018-06-14 16:50:35.996404 CDT" "2018-06-14 16:50:35.766226 CDT"
[3] "2018-06-14 16:50:37.324935 CDT" "2018-06-14 16:50:37.395443 CDT"
[5] "2018-06-14 16:50:37.524731 CDT"
R> 

Once you understand the base types, there is little need for add-on packages as everything just works in (fractional) seconds. So to add an hour, it is 60*60 and so on. Add-on packages are still useful business-day conventions, holidays and additional parsers.

Your problem in your code snippet was that the format() destroys the Datetime object: you asked R to create a string, which it did. On those you no longer can do math. Ergo, do the math first, then pretty-print or format.

like image 151
Dirk Eddelbuettel Avatar answered Jan 01 '23 18:01

Dirk Eddelbuettel


When you use the format function, you create a character variable that cannot be sum. Therefore, I would suggest to keep then as POSIXt and use as character when necessary

Also, the minutes and hours functions from lubridate create a period object that is converted to a number when in a list (I don't completely understand this part here) and I could not sum using lists.

Anyways, if I understand propperly, I have manage to get the results you wanted by working with no list (you can put the results after on one, if you may) with the code:

hourTime<-(seq.POSIXt(as.POSIXct(Sys.Date()),
                         as.POSIXct(Sys.Date()+1),
                         by = "5 min"))


ARRIVALTIME <- sample(hourTime, 1000, replace=T)
TRETTIME <- ARRIVALTIME +
    (hours(sample(1:3, 1000, replace=T)) +
                     minutes(sample(1:60, 1000, replace=T)))
like image 35
André Costa Avatar answered Jan 01 '23 17:01

André Costa