2011-11-20 74 views
5

我正在爲R函數搜索全部幫助,例如轉換時間範圍在日期時間對象「00:15:00」或「01:00:00」或「00:00:06」或「1960年」中將「15分鐘」或「1小時」或「6秒」或「 01-02 00:00:00「(不確定這個)。我相信這樣的函數存在或有一個簡潔的方法來避免編程它...從時間跨度(例如「15分鐘」或「2秒」)到「00:15:00」或「00:00:02」

更具體地說,我想要做這樣的事情(使用組成函數名稱transform.span.to.time ):

library(chron) 

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

其應產生相同的結果

times("00:15:00") 

是否像transform.span.to.time( 「15分鐘」)的函數的返回像「〇點15分00秒「存在還是存在如何做到這一點的訣竅?

回答

3

基座功能?cut.POSIXt執行此工作指定的一組值的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.* 

cut.POSIXt鍵入見的源代碼,相關部分始於此:

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

您可以採用本節中的代碼來滿足您的需求。

6

我們將假定一個單獨的空格將數字和單位分開,並且在「secs」單位之後也沒有尾隨空格。這將處理混合單位:

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:謝謝。

基於迪文例子中,我重新整理了一下,這裏是結果:

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

您可以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") 
} 

例如:

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

編輯:修改爲產生chron的可接受字符串的times

4

第一種解決方案在gsubfn軟件包中使用strapply,並轉換爲數天,例如, 1小時是一天的第24天。第二種解決方案轉換爲R表達式,計算天數並對其進行評估。

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) 

這裏是第二溶液:

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)) 
} 

測試:

> 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