adding hours and minutes to 24 hour time in R - r

Im trying to find a way to create a column of the hours of arrival of different individuals from 18:30, by adding the hours and minutes to 18:30, but it doesnt work, and each time I try to convert the column format, of the hours and minutes I want to add, from "factor" to a time format (such as chron or POSIXct)it adds today`s date and I want to add only the hours and minutes without considering date.
For example, I want to add 03:38 hours to 18:30, which will be 22:08. So, I want to find a way to have a column with all the final hours (hours of arrival of each individual). another example is adding 00:47 hours to 18:30 which is 19:17.
I tried to do it by converting the hours+minutes to a numeric format and than add it to 18.5 (which is 18:30, just in a numeric format), and I reached final hours, but they are in a numeric format, and I wish them to be in an hour format. For example:
I added 3.6425980 (which is 03:38) to 18.5 (which is 18:30) and the final hour was 22.14260 (which is 22:08), but I don`t know how to convert 22.14260 to 22:08.
I need to do it for a lot of data, so I need a code that does one of the above things.
Can someone help me?
thanks!

One option is to use lubridate
time <- c("18:30", "18:30")
duration <- c("3:38", "00:47")
library(lubridate)
hms(hm(time) + hm(duration), roll = T)
#[1] "22H 8M 0S" "19H 17M 0S"

Related

In R convert a list of numbers that represent time in hours to a POSIXct or Date variable format

I have a list of times that are an output of a model, these are in a decimal number format and represent the time from the start of the model running in hours, but they have not been given any units in the output, they are just numbers.
What I would like to do is convert these numbers into a date stamp format, using the numbers as hours the model has run. Specifically as either a POSIXct or Date variable so I can start use the Bupar library.
So for example I would like to convert 1.75, into 1 hour 45 minutes and 25.5 into a time that would equal 1 day 1 hour and 30 mins.
Thanks for any help
One possible way:
We could use seconds_to_period() function from lubridate after multiplying by 3600 to get seconds:
library(lubridate)
x <- 1.75
seconds_to_period(x*3600)
#[1] "1H 45M 0S"

lubridate - get hours and minutes from decimal hours

I have decimal hours in format 245.85 equalling to 245:51:00 in [hh]:mm:ss format.
I want to transform the decimal hours to hh:mm format, but how do I do it?
the original calculation that renders 245.85 is:
library(lubridate)
time_length(hm("7 27")*33,unit = "hours")
what I want is 245:51 or 245:51:00
If I use as.period I get days too - like in:
as.period(dhours(time_length(hm("7 27")*33,"hours")))
[1] "10d 5H 51M 0S"
and for background - my aim is to multiply hours and minutes (e.g. 7:27) by an arbitrary integer (e.g. 33) and get result back in hh:mm format - avoiding days (as in as.period example above). Say if a piece of work takes 7 hours and 27 minutes and we give me 33 pieces of such work to do per year, it should take me about this many work hours (and minutes) to do.
If it's really only the H:M:S format that gives you trouble, try
library(hms)
hms(hours=245.85)
which yields 245:51:00

How to convert times over 24:00:00 in R

In R I have this data.frame
24:43:30 23:16:02 14:05:44 11:44:30 ...
Note that some of the times are over 24:00:00 ! In fact all my times are within 02:00:00 to 25:59:59.
I want to subtract all entries in my dataset data with 2 hours. This way I get a regular data-set. How can I do this?
I tried this
strptime(data, format="%H:%M:%S") - 2*60*60
and this work for all entries below 23:59:59. For all entries above I simply get NA since the strptime command produce NA to all entries above 23:59:59.
Using lubridate package can make the job easier!
> library(lubridate)
> t <- '24:43:30'
> hms(t) - hms('2:0:0')
[1] "22H 43M 30S"
Update:
Converting the date back to text!
> substr(strptime(hms(t) - hms('2:0:0'),format='%HH %MM %SS'),12,20)
[1] "22:43:30"
Adding #RHertel's update:
format(strptime(hms(t) - hms('2:0:0'),format='%HH %MM %SS'),format='%H:%M:%S')
Better way of formating the lubridate object:
s <- hms('02:23:58) - hms('2:0:0')
paste(hour(s),minute(s),second(s),sep=":")
"0:23:58"
Although the answer by #amrrs solves the main problem, the formatting could remain an issue because hms() does not provide a uniform output. This is best shown with an example:
library(lubridate)
hms("01:23:45")
#[1] "1H 23M 45S"
hms("00:23:45")
#[1] "23M 45S"
hms("00:00:45")
#[1] "45S"
Depending on the time passed to hms() the output may or may not contain an entry for the hours and for the minutes. Moreover leading zeros are omitted in single-digit values of hours, minutes and seconds. This can result pretty much in a formatting nightmare if one tries to put that data into a common form.
To resolve this difficulty one could first convert the time into a duration with lubridate's as.duration() function. Then, the duration in seconds can be transformed into a POSIXct object from which the hours, minutes, and seconds can be extracted easily with format():
times <- c("24:43:30", "23:16:02", "14:05:44", "11:44:30", "02:00:12")
shifted_times <- hms(times) - hms("02:00:00")
format(.POSIXct(as.duration(shifted_times),tz="GMT"), "%H:%M:%S")
#[1] "22:43:30" "21:16:02" "12:05:44" "09:44:30" "00:00:12"
The last entry "02:00:12" would have caused difficulties if shifted_times had been passed to strptime().

Creating a specific sequence of date/times in R

I want to create a single column with a sequence of date/time increasing every hour for one year or one month (for example). I was using a code like this to generate this sequence:
start.date<-"2012-01-15"
start.time<-"00:00:00"
interval<-60 # 60 minutes
increment.mins<-interval*60
x<-paste(start.date,start.time)
for(i in 1:365){
print(strptime(x, "%Y-%m-%d %H:%M:%S")+i*increment.mins)
}
However, I am not sure how to specify the range of the sequence of dates and hours. Also, I have been having problems dealing with the first hour "00:00:00"? Not sure what is the best way to specify the length of the date/time sequence for a month, year, etc? Any suggestion will be appreciated.
I would strongly recommend you to use the POSIXct datatype. This way you can use seq without any problems and use those data however you want.
start <- as.POSIXct("2012-01-15")
interval <- 60
end <- start + as.difftime(1, units="days")
seq(from=start, by=interval*60, to=end)
Now you can do whatever you want with your vector of timestamps.
Try this. mondate is very clever about advancing by a month. For example, it will advance the last day of Jan to last day of Feb whereas other date/time classes tend to overshoot into Mar. chron does not use time zones so you can't get the time zone bugs that code as you can using POSIXct. Here x is from the question.
library(chron)
library(mondate)
start.time.num <- as.numeric(as.chron(x))
# +1 means one month. Use +12 if you want one year.
end.time.num <- as.numeric(as.chron(paste(mondate(x)+1, start.time)))
# 1/24 means one hour. Change as needed.
hours <- as.chron(seq(start.time.num, end.time.num, 1/24))

what is the best practice of handling time in R?

I am working with a survey dataset. It has two string vectors, start and finish, indicating the time of the day when the interview was started, and finished, respectively.
They are character strings that look like: "9:24 am", "12:35 pm", and so forth. I am trying to calculate the duration of the interview based on these two. What is the best way of doing this?
I know that, for dates, there are lots of classes or functions like as.date(), as.Date(), chron(), or as.POSIXct(). So I was looking for something like as.time(), but could not find it. Should I just append a made-up date and convert the whole thing into a POSIX() date-time class, then use difftime()?
What is the best practice of handling time in R?
You need to use strptime() to convert the string to a date. For example:
strptime("9:24 am",format="%I:%M %p")
Then you can take differences just by taking one away from the other:
strptime("9:24 am",format="%I:%M %p")-strptime("12:14 am",format="%I:%M %p")
Time difference of 9.166667 hours
You can store this and then do an as.numeric() if you just want the number out, otherwise you can pass around the time objects.
Hope this helps!
one option is to use regular expressions. if you are not familiar with them, they are used to parse strings using patterns. i would research regular expressions and then here are the functions in r
hope it helps
best practice is using lubridate package
https://www.rdocumentation.org/packages/lubridate/versions/1.5.6/topics/hm
hm(c("09:10", "09:02", "1:10"))
## [1] "9H 10M 0S" "9H 2M 0S" "1H 10M 0S
Then use difftime for difference in the date time formats created above
https://stat.ethz.ch/R-manual/R-devel/library/base/html/difftime.html
difftime(time1, time2, tz,
units = c("auto", "secs", "mins", "hours",
"days", "weeks"))

Resources