2011-11-20 51 views
5

Tôi đang tìm kiếm tất cả trợ giúp cho hàm R có thể chuyển đổi timespan, ví dụ "15 phút" hoặc "1 giờ" hoặc "6 giây" hoặc "1 ngày" vào đối tượng ngày giờ như "00:15:00" hoặc "01:00:00" hoặc "00:00:06" hoặc "1960- 01-02 00:00:00 "(không chắc chắn cho điều này). Tôi chắc chắn một chức năng như thế này tồn tại hoặc có một cách gọn gàng để tránh lập trình ...Từ thời gian (ví dụ "15 phút" hoặc "2 giây") thành "00:15:00" hoặc "00:00:02"

Để cụ thể hơn, tôi muốn thực hiện một cái gì đó như thế này (sử dụng tên hàm được tạo thành transform.span.to.time):

library(chron) 

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

mà phải mang lại kết quả tương tự như

times("00:15:00") 

Liệu một chức năng như transform.span.to.time ("15 phút") trả về một cái gì đó như "00:15:00 "tồn tại hay không tồn tại một mẹo làm thế nào để làm điều đó?

Trả lời

3

Chức năng cơ bản ?cut.POSIXt làm tác phẩm này với một bộ quy định các giá trị cho 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.* 

Xem mã nguồn bằng cách gõ cut.POSIXt, phần có liên quan bắt đầu với điều này:

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

Bạn có thể áp dụng mã trong phần này để làm việc cho nhu cầu của bạn.

6

Chúng tôi sẽ giả định một khoảng trống tách các số và đơn vị, đồng thời không có dấu cách sau đơn vị "giây". Thao tác này sẽ xử lý các đơn vị hỗn hợp:

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: cảm ơn bạn.

Dựa trên DWin Ví dụ: Tôi sắp xếp lại một chút và đây là kết quả:

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

Bạn có thể xác định khoảng thời gian với 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") 
} 

Ví dụ:

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

EDIT: được sửa đổi để tạo chuỗi ký tự được chấp nhận chocủa chron.

4

Giải pháp đầu tiên sử dụng strapply trong gói gsubfn và biến đổi thành ngày, ví dụ: 1 giờ là 1/24/ngày. Giải pháp thứ hai biến thành một biểu thức R tính toán số ngày và sau đó đánh giá nó.

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) 

Dưới đây là một giải pháp thứ hai:

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

Các xét nghiệm:

> 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 
Các vấn đề liên quan