2013-05-29 41 views
9

Tôi đang tìm kiếm các ngày theo nhóm trong R theo mức độ chính xác tùy ý.làm tròn một ngày trong R đến mức độ chính xác tùy ý

Khá đơn giản để thực hiện việc này đến giờ hoặc phút gần nhất, bằng cách sử dụng ví dụ: lubridate:

library(lubridate) 
nearest_hour = floor_date(now(), 'hour') 

Sau đó, bạn có thể nhóm danh sách các ngày như vậy, ví dụ: một đơn giản summariseddply từ plyr.

Điều tôi muốn làm là các ngày tròn có độ chính xác tùy ý, ví dụ: đến 15 phút gần nhất hoặc mỗi 3 giờ:

nearest_three_hours = floor_date(now(), '3 hours') 

Có một cuộc thảo luận về điều đó tại http://r.789695.n4.nabble.com/Truncating-dates-and-other-date-time-manipulations-td866901.html nhưng bên ngoài cắt ngày, có không xuất hiện như đã được giải quyết bất kỳ.

Bất kỳ trợ giúp nào được đánh giá cao! Cảm ơn bạn.

+2

Nếu bạn có một vector của lần để tập hợp con từ, sau đó bạn có thể sử dụng hàm 'endpoints' trong [xts] (http://cran.project.org/package=xts):' library (xts); x <- .POSIXct (0) +1: 10 * 60 * 60 ; x [điểm cuối (x, "giờ", 3)] ' – GSee

Trả lời

5

lubridate đã làm sàn cho đơn vị nguyên tử gần nhất. Để có được sàn đến 15 phút gần nhất, mà tôi nghĩ là những gì bạn muốn làm (không tròn), bạn chỉ cần ánh xạ vào phạm vi chính xác thông qua findInterval và một bộ các điểm ngắt xác định. Hãy thử floor_time này, có chức năng tương đương với floor_date, nhưng cho phép bạn chỉ định một biến số đơn vị cho giây, phút hoặc giờ.

floor_time <- function(x, k = 1, unit = c("second", "minute", "hour", "day", 
              "week", "month", "year")) { 
    require(lubridate) 

    nmax <- NULL 

    switch(unit, second = {nmax <- 60}, 
     minute = {nmax <- 60}, 
     hour = {nmax <- 24}) 

    cuts <- seq(from = 0, to = nmax - 1, by = k) 
    new <- switch(unit, 
       second = update(x, seconds = cuts[findInterval(second(x), cuts)]), 
       minute = update(x, minutes = cuts[findInterval(minute(x), cuts)], 
           seconds = 0), 
       hour = update(x, hours = cuts[findInterval(hour(x), cuts)], 
           minutes = 0, seconds = 0), 
       day = update(x, hours = 0, minutes = 0, seconds = 0), 
       week = update(x, wdays = 1, hours = 0, minutes = 0, seconds = 0), 
       month = update(x, mdays = 1, hours = 0, minutes = 0, seconds = 0), 
       year = update(x, ydays = 1, hours = 0, minutes = 0, seconds = 0)) 

    new 
} 
5

Bạn có thể thử này, vẫn dựa trên các thư viện lubridate

library(lubridate) 
round_minute<-function(x,precision){ 
    m<-minute(x)+second(x)/60 
    m.r<- round(m/precision)*precision 
    minute(x)<-m.r 
    second(x)<-0 
    x 
} 

round_minute(ymd_hms(c("2013-06-03 22:53:00","2013-05-03 12:18:00","2013-05-03 00:10:00")),15) 

> "2013-06-03 23:00:00 UTC" "2013-05-03 12:15:00 UTC" "2013-05-03 00:15:00 UTC" 

Mã này xử lý tốt tất cả các tình huống phức tạp nhờ lubridate. Tất nhiên chức năng này chỉ hoạt động với độ chính xác được biểu thị bằng phút nhưng bạn có thể dễ dàng mở rộng nó đến các đơn vị khác và thậm chí tạo ra một hàm chung nếu bạn thực sự cần nó.

1

lubridate bây giờ có một round_date() hàm tổng quát hơn.

lubridate::round_date(date, "5 mins") 
lubridate::round_date(date, "2 hours") 
1

Một chút muộn, và tôi không có đại diện để bình luận, nhưng như Selva đã đề cập, lubridate hiện nay có chức năng này:

library(lubridate) 
round_date(now(), '3 hours') 
floor_date(now(), '3 hours') 
ceiling_date(now(), '3 hours') 
Các vấn đề liên quan