R extract time components from semi-standard strings

前端 未结 2 453
孤独总比滥情好
孤独总比滥情好 2021-01-12 09:16

Setup

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

相关标签:
2条回答
  • 2021-01-12 09:58

    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.

    0 讨论(0)
  • 2021-01-12 10:07

    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)
    
    0 讨论(0)
提交回复
热议问题