2013-05-29 3 views
9

Ich bin auf der Suche nach Daten in R mit einer beliebigen Genauigkeit zu gruppieren.Runden Sie ein Datum in R auf ein beliebiges Maß an Genauigkeit

Es ist ziemlich einfach, dies auf die nächste Stunde oder Minute zu tun, z. lubridate:

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

können Sie dann die Gruppe eine Liste solcher Termine mit z.B. eine einfache summariseddply von plyr.

Was ich tun möchte, ist runde Daten mit beliebiger Genauigkeit, z. auf die nächsten 15 Minuten oder alle 3 Stunden:

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

Es gibt eine Diskussion über solche Dinge bei http://r.789695.n4.nabble.com/Truncating-dates-and-other-date-time-manipulations-td866901.html aber außerhalb Daten des Schneidens, angezeigt wird es keine Auflösung gewesen zu sein.

Jede Hilfe wird geschätzt! Vielen Dank.

+2

Wenn Sie einen Vektor Mal aus der Teilmenge, dann Sie könnten die Funktion 'endpoints' in [xts] (http://cran.project.org/package=xts) verwenden: 'library (xts); x <- .POSIXct (0) +1: 10 * 60 * 60 ; x [Endpunkte (x, "Stunden", 3)] ' – GSee

Antwort

5

lubridate bereits Böden auf die nächste Atomeinheit. Um den Boden auf die nächsten 15 Minuten zu bringen, was ich denke, was Sie tun möchten (nicht rund), müssen Sie nur über findInterval und einen definierten Satz von Haltepunkten in den richtigen Bereich mappen. Probieren Sie diese floor_time aus, die funktional mit floor_date übereinstimmt, aber Sie können eine variable Anzahl von Einheiten für Sekunden, Minuten oder Stunden angeben.

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

Sie können dies versuchen, auf dem

Der Code behandeln und alle schwierigen Situationen dank 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" 
lubridate Bibliothek noch basiert. Natürlich funktioniert diese Funktion nur für die in Minuten ausgedrückte Genauigkeit, aber Sie können sie leicht auf andere Einheiten erweitern und sogar eine generische Funktion erstellen, wenn Sie sie wirklich brauchen.

1

lubridate hat jetzt eine allgemeinere round_date() Funktion.

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

Ein wenig spät, und ich habe nicht rep zu kommentieren, aber wie Selva erwähnt, lubridate hat nun diese Funktionalität:

library(lubridate) 
round_date(now(), '3 hours') 
floor_date(now(), '3 hours') 
ceiling_date(now(), '3 hours')