Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to calculate duration from a "start - end" string more succinctly [duplicate]

I have times stamps indicating the time an event started and the time it ended:

x <- "00:01:00.000 - 00:01:10.500"

I need to calculate the event's duration. Using hmsfrom the package lubridateas well as lapply and strsplitdoes give me the expected output:

library(lubridate)
unlist(lapply(strsplit(x, split=" - "), function(x) as.numeric(hms(x))))[2] - unlist(lapply(strsplit(x, split=" - "), function(x) as.numeric(hms(x))))[1] 
[1] 10.5

But I feel the code is utterly inelegant and anything but succinct. Is there any better way to get the duration?

EDIT:

What if, as is indeed the case, there are many more than just one value in x, such as:

x <- c("00:01:00.000 - 00:01:10.500", "00:12:12.000 - 00:13:10.500")

I've come up with this solution:

timepoints <- lapply(strsplit(x, split=" - "), function(x) as.numeric(hms(x)))
duration <- lapply(timepoints, function(x) x[2]-x[1])

duration
[[1]]
[1] 10.5

[[2]]
[1] 58.5

But, again, there's surely a nicer and shorter one.

like image 533
Chris Ruehlemann Avatar asked Dec 23 '22 17:12

Chris Ruehlemann


1 Answers

Here is a way :

as.numeric(diff(lubridate::hms(strsplit(x, split=" - ")[[1]])))
#[1] 10.5

Keeping it in base R :

as.numeric(diff(as.POSIXct(strsplit(x, split=" - ")[[1]], format = '%H:%M:%OS')))
#[1] 10.5

For multiple values, we can use sapply :

library(lubridate)
sapply(strsplit(x, " - "), function(y) diff(period_to_seconds(hms(y))))

#[1] 10.5 80.5

and in base R :

sapply(strsplit(x, " - "), function(y) {
   x1 <- as.POSIXct(y, format = '%H:%M:%OS')
   difftime(x1[2], x1[1], units = "secs")
})
like image 175
Ronak Shah Avatar answered Jan 31 '23 01:01

Ronak Shah