2013-05-29 10 views
9

Czekam na grupowanie dat w R z arbitralnym poziomem precyzji.zaokrąglić datę w R do arbitralnego poziomu precyzji

To całkiem proste, aby zrobić to do najbliższej godziny lub minuty, używając np. lubridate:

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

Następnie można pogrupować listę takich dat, np. prosty summarise z plyr.

Co chcę zrobić, to zaokrąglić daty z dowolną precyzją, np. z dokładnością do 15 minut lub co 3 godziny:

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

Istnieje dyskusja o takich rzeczach w http://r.789695.n4.nabble.com/Truncating-dates-and-other-date-time-manipulations-td866901.html ale poza cięcia termin, nie wydaje się być dowolną rozdzielczość.

Każda pomoc doceniona! Dziękuję Ci.

+2

Jeśli masz wektor czas do podzbioru z, a następnie możesz użyć funkcji 'endpoints' w [xts] (http://cran.project.org/package=xts):' library (xts); x <- .POSIXct (0) +1: 10 * 60 * 60 ; x [punkty końcowe (x, "godziny", 3)] ' – GSee

Odpowiedz

5

lubrykować już podłogi do najbliższej jednostki atomowej. Aby uzyskać piętro z dokładnością do 15 minut, co moim zdaniem jest tym, co chcesz zrobić (nie zaokrąglać), musisz po prostu odwzorować właściwy zakres za pomocą funkcji findInterval i zdefiniowanego zestawu punktów przerwania. Spróbuj tego floor_time, który jest funkcjonalnie równoważny floor_date, ale pozwala określić zmienną # jednostek na sekundy, minuty lub godziny.

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

Możesz spróbować tego, nadal opiera się na lubridate biblioteki

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" 

Kod dobrze obsłużyć wszystkich trudnych sytuacjach dzięki lubridate. Oczywiście ta funkcja działa tylko w przypadku precyzji wyrażonej w minutach, ale można ją łatwo rozszerzyć na inne jednostki, a nawet utworzyć funkcję ogólną, jeśli naprawdę jej potrzebujesz.

1

lubridate ma teraz bardziej ogólny round_date() funkcję.

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

Trochę późno, a ja nie mam rep wypowiedzenia, ale jak wspomniano Selva, lubridate ma teraz tę funkcję:

library(lubridate) 
round_date(now(), '3 hours') 
floor_date(now(), '3 hours') 
ceiling_date(now(), '3 hours') 
Powiązane problemy