2017-02-27 18 views
3

在對時間戳數據進行預測建模時,我想在R中編寫一個函數(可能使用data.table),將日期舍入X小時。例如。 2小時四捨五入應該給這個:在R中X小時的輪次?

"2014-12-28 22:59:00 EDT" becomes "2014-12-28 22:00:00 EDT" 
"2014-12-28 23:01:00 EDT" becomes "2014-12-29 00:00:00 EDT" 

這是很容易做到的輪1小時,當你 - 使用round.POSIXt(.date, "hour")功能。
編寫一個通用的功能,就像我做以下使用多個if語句,變得很醜陋但是:

d7.dateRoundByHour <- function (.date, byHours) { 

    if (byHours == 1) 
    return (round.POSIXt(.date, "hour")) 

    hh = hour(.date); dd = mday(.date); mm = month(.date); yy = year(.date)  
    hh = round(hh/byHours,digits=0) * byHours 
    if (hh>=24) { 
    hh=0; dd=dd+1 
    } 
    if ((mm==2 & dd==28) | 
     (mm %in% c(1,3,5,7,8,10,12) & dd==31) | 
     (mm %in% c(2,4,6,9,11) & dd==30)) { # NB: it won't work on 29 Feb leap year. 
    dd=1; mm=mm+1 
    } 
    if (mm==13) { 
    mm=1; yy=yy+1 
    } 
    str = sprintf("%i-%02.0f-%02.0f %02.0f:%02.0f:%02.0f EDT", yy,mm,dd, hh,0,0) 
    as.POSIXct(str, format="%Y-%m-%d %H:%M:%S") 
} 

任何人都可以表現出更好的方式來做到這一點?
(也許通過轉換爲數字和回POSIXt或一些其它功能POSIXt?)

+1

包'highfrequency'有一個名爲'aggregatets()'的包裝,它應該給你想要的結果 – Rime

回答

3

使用從lubridate包round_date功能。假設你有一個名爲日期列data.table你可以做到以下幾點:

dt[, date := round_date(date, '2 hours')] 

一個簡單的例子會給你正是你要找的結果:

x <- as.POSIXct("2014-12-28 22:59:00 EDT") 
round_date(x, '2 hours') 
3

其實,這是真的易只有立足R.圓形的基本思想是「零碎」你

  • 規模下降了適當的比例因子
  • 圓鋼d下降到按比例縮小的單位整數
  • 規模回升,並重新轉換

或者在兩個R代碼語句:

R> pt <- as.POSIXct(c("2014-12-28 22:59:00", "2014-12-28 23:01:00 EDT")) 
R> pt # just to check 
[1] "2014-12-28 22:59:00 CST" "2014-12-28 23:01:00 CST" 
R> 
R> scalefactor <- 60*60*2 # 2 hours of 60 minutes times 60 seconds 
R> 
R> as.POSIXct(round(as.numeric(pt)/scalefactor) * scalefactor, origin="1970-01-01") 
[1] "2014-12-28 22:00:00 CST" "2014-12-29 00:00:00 CST" 
R> 

關鍵的最後一行少了點什麼,我概括:轉換POSIXct轉換爲數字表示,將其縮小,然後進行舍入,然後再縮小並再次轉換爲POSIXct