I have a column of durations stored as a strings in a dataframe. I want to convert them to an appropriate time object, probably POSIXlt. Most of the strings
I think you will have better luck with lubridate:
From Dates and Times Made Easy with lubridate:
5.3. Durations
...
The length of a duration is invariant to leap years, leap seconds, and daylight savings time because durations are measured in seconds. Hence, durations have consistent lengths and can be easily compared to other durations. Durations are the appropriate object to use when comparing time based attributes, such as speeds, rates, and lifetimes. lubridate uses the difftime class from base R for durations. Additional difftime methods have been created to facilitate this.
lubridate uses the difftime class from base R for durations. Additional difftime methods have been created to facilitate this.
...
Duration objects can be easily created with the helper functions dyears(), dweeks(), ddays(), dhours(), dminutes(), and dseconds(). The d in the title stands for duration and distinguishes these objects from period objects, which are discussed in Section 5.4. Each object creates a duration in seconds using the estimated relationships given above.
That said, I haven't (yet) found a function to parse a string into a duration.
You might also take a look at Ruby's Chronic to see how elegant time parsing can be. I haven't found a library like this for R.
difftime
objects are time duration objects that can be added to either POSIXct
or POSIXlt
objects. Maybe you want to use this instead of POSIXlt
?
Regarding the conversion from strings to time objects, you could do something like this:
data <- data.frame(time.string = c(
"1 d 1 h",
"30 m 10 s",
"1 d 2 h 3 m 4 s",
"2 h 3 m 4 s",
"10 d 20 h 30 m 40 s",
"--"))
f <- function(x) {
x <- as.character(x)
format <- paste(c(if (grepl('d', x)) '%j d',
if (grepl('h', x)) '%H h',
if (grepl('m', x)) '%M m',
if (grepl('s', x)) '%S s'), collapse=' ')
if (nchar(format) > 0) {
if (grepl('%j d', format)) {
# '%j 1' is day 0. We add a day so that x = '1 d' means 24hrs.
difftime(as.POSIXct(x, format=format) + as.difftime(1, units='days'),
cut(Sys.Date(), breaks='years'),
units='hours')
} else {
as.difftime(x, format, units='hours')
}
} else { NA }
}
data$time.span <- sapply(data$time.string, FUN=f)