2011-11-20 20 views
5

Estoy buscando ayuda para la función R que convertiría el intervalo de tiempo, por ejemplo "15 min" o "1 hora" o "6 seg" o "1 día" en el objeto datetime como "00:15:00" o "01:00:00" o "00:00:06" o "1960- 01-02 00:00:00 "(no estoy seguro de esto). Estoy seguro de que existe una función como esta o hay una forma ordenada de evitar su programación ...Desde el intervalo de tiempo (por ejemplo "15 min" o "2 segundos") hasta "00:15:00" o "00:00:02"

Para ser más específicos, me gustaría hacer algo como esto (usando el nombre de la función inventada transform.span.to.time):

library(chron) 

times(transform.span.to.time("15 min")) 

que debe producir el mismo resultado que

times("00:15:00") 

funciona una como transform.span.to.time ("15 min") que devuelve algo como "00:15:00 "existe o existe un truco de cómo hacer eso?

Respuesta

3

La función de base ?cut.POSIXt hace este trabajo para un conjunto determinado de valores para breaks:

breaks: a vector of cut points _or_ number giving the number of 
     intervals which ‘x’ is to be cut into *_or_ an interval 
     specification, one of ‘"sec"’, ‘"min"’, ‘"hour"’, ‘"day"’, 
     ‘"DSTday"’, ‘"week"’, ‘"month"’, ‘"quarter"’ or ‘"year"’, 
     optionally preceded by an integer and a space, or followed by 
     ‘"s"’. For ‘"Date"’ objects only ‘"day"’, ‘"week"’, 
     ‘"month"’, ‘"quarter"’ and ‘"year"’ are allowed.* 

Ver el código fuente tecleando cut.POSIXt, la sección correspondiente comienza con esto:

else if (is.character(breaks) && length(breaks) == 1L) { 

Puede adoptar el código en esta sección para trabajar según sus necesidades.

6

Supondremos un espacio único que separa los números y las unidades, y tampoco el espacio posterior después de la unidad "secs". Esto manejará unidades mixtas:

test <- "0 hours 15 min 0 secs" 

transform.span <- function(test){ 
    testh <-   if(!grepl(" hour | hours ", "0 hours 15 min 0 secs")){ 
      # First consequent if no hours 
             sub("^", "0:", test)} else { 
             sub(" hour | hours ", ":", test)} 
    testm <- if(!grepl(" min | minutes ", testh)) {  
      # first consequent if no minutes 
             sub(" min | minutes ", "0:", testh)} else{ 
             sub(" min | minutes ", ":", testh) } 

    test.s <- if(!grepl(" sec| secs| seconds", testm)) { 
       # first consequent if no seconds 
             sub(" sec| secs| seconds", "0", testm)} else{ 
             sub(" sec| secs| seconds", "", testm)} 

    return(times(test.s)) } 
### Use 
> transform.span(test) 
[1] 00:15:00 
> test2 <- "21 hours 15 min 38 secs" 
> transform.span(test2) 
[1] 21:15:38 
2

@DWin: gracias.

basado en el ejemplo Dwin reacomodé un poco y aquí está el resultado:

transform.span<-function(timeSpan) { 
    timeSpanH <- if(!grepl(" hour | hours | hour| hours|hour |hours |hour|hours", timeSpan)) { 
       # First consequent if no hours 
       sub("^", "00:", timeSpan) 
      } else { 
       sub(" hour | hours | hour| hours|hour |hours |hour|hours", ":", timeSpan) 
      } 
    timeSpanM <- if(!grepl(" min | minutes | min| minutes|min |minutes |min|minutes", timeSpanH)) {  
       # first consequent if no minutes 
       paste("00:", timeSpanH, sep="") 
      } else{ 
       sub(" min | minutes | min| minutes|min |minutes |min|minutes", ":", timeSpanH) 
      } 
    timeSpanS <- if(!grepl(" sec| secs| seconds|sec|secs|seconds", timeSpanM)) { 
       # first consequent if no seconds 
       paste(timeSpanM, "00", sep="") 
      } else{ 
       sub(" sec| secs| seconds|sec|secs|seconds", "", timeSpanM) 
      } 

    return(timeSpanS) 
} 
### Use 
test <- "1 hour 2 min 1 sec" 
times(transform.span(test)) 
test1hour <- "1 hour" 
times(transform.span(test1hour)) 
test15min <- "15 min" 
times(transform.span(test15min)) 
test4sec <- "4 sec" 
times(transform.span(test4sec)) 
3

puede definir el lapso de tiempo con difftime:

span2time <- function(span, units = c('mins', 'secs', 'hours')) { 
    span.dt <- as.difftime(span, units = match.arg(units)) 
    format(as.POSIXct("1970-01-01") + span.dt, "%H:%M:%S") 
} 

Por ejemplo:

> span2time(15) 
[1] "00:15:00" 

EDITAR: modificado para producir cadena de caracteres aceptable para chron's times.

4

La primera solución usa strapply en el paquete gsubfn y se transforma en días, p. Ej. 1 hora es 1/24 de un día. La segunda solución se transforma en una expresión R que calcula el número de días y luego lo evalúa.

library(gsubfn) 
library(chron) 

unit2days <- function(d, u) 
    as.numeric(d) * switch(tolower(u), s = 1, m = 60, h = 3600)/(24 * 3600) 
transform.span.to.time <- function(x) 
    sapply(strapply(x, "(\\d+) *(\\w)", unit2days), sum) 

Aquí está una segunda solución:

library(chron) 

transform.span.to.time2 <- function(x) { 
    x <- paste(x, 0) 
    x <- sub("h\\w*", "*3600+", x, ignore.case = TRUE) 
    x <- sub("m\\w*", "*60+", x, ignore.case = TRUE) 
    x <- sub("s\\w*", "+", x, ignore.case = TRUE) 
    unname(sapply(x, function(x) eval(parse(text = x)))/(24*3600)) 
} 

Análisis:

> x <- c("12 hours 3 min 1 sec", "22h", "18 MINUTES 23 SECONDS") 
> 
> times(transform.span.to.time(x)) 
[1] 12:03:01 22:00:00 00:18:23 
> 
> times(transform.span.to.time2(x)) 
[1] 12:03:01 22:00:00 00:18:23 
Cuestiones relacionadas