2013-05-29 47 views
9

我期待通過任意級別的精度將R中的日期分組。將R中的日期舍入到任意精度級別

這是非常簡單的做到這一點到最近的小時或分鐘,使用例如。 lubridate

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

然後,您可以組這樣的日期與例如列表一個簡單的summariseddplyplyr

我想要做的是具有任意精度的圓形日期,例如到最近的15分鐘或每3個小時:

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

有在http://r.789695.n4.nabble.com/Truncating-dates-and-other-date-time-manipulations-td866901.html這樣的事情的討論,但切割日期之外,有沒有出現過任何決議。

任何幫助表示讚賞!謝謝。

+2

如果你有時間的矢量從,然後於子集你可以在[xts](http://cran.project.org/package=xts)中使用'endpoints'函數:'library(xts); x < - .POSIXct(0)+1:10 * 60 * 60 ; x [終點(x,「小時」,3)]' – GSee

回答

5

lubridate已經樓層到最近的原子單位。爲了達到最接近的15分鐘,我認爲這是你想要做的(不是圓的),你只需要通過findInterval和一組定義的斷點映射到正確的範圍。試試這個floor_time,它在功能上等同於floor_date,但是允許你指定一個變量的秒數,分鐘或小時數。

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

你可以試試這個,仍然是基於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。當然,這個函數只適用於以分鐘表示的精度,但您可以輕鬆地將其擴展到其他單位,甚至在您真正需要時創建通用函數。

1

lubridate現在有一個更通用round_date()功能。

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

有點晚,而且我也沒有代表對此發表評論,但作爲塞爾瓦提到,現在lubridate具有此功能:

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