2016-04-24 79 views
5

我這是按以下方式格式化的一些數據:從R中的精確數據創建15分鐘的時間間隔?

time  count 
00:00 17 
00:01 62 
00:02 41 

所以,我必須從00:00到23:59小時和每分鐘的計數器。我想在組間隔15分鐘的數據使得:

time   count 
00:00-00:15 148 
00:16-00:30 284 

我試圖做手工,但這是很耗費精力,所以我敢肯定,必須有一個函數或某事很容易做到這一點但我還沒有想出如何去做。

我真的很感謝一些幫助!

非常感謝!

回答

7

對於處於POSIXct格式的數據,您可以使用cut函數創建15分鐘的分組,然後按這些組進行聚合。下面的代碼顯示瞭如何在base R以及dplyrdata.table程序包中執行此操作。

首先,創建一些假數據:

set.seed(4984) 
dat = data.frame(time=seq(as.POSIXct("2016-05-01"), as.POSIXct("2016-05-01") + 60*99, by=60), 
       count=sample(1:50, 100, replace=TRUE)) 

基礎R

cut數據分成15分鐘組:

dat$by15 = cut(dat$time, breaks="15 min") 
    time count    by15 
1 2016-05-01 00:00:00 22 2016-05-01 00:00:00 
2 2016-05-01 00:01:00 11 2016-05-01 00:00:00 
3 2016-05-01 00:02:00 31 2016-05-01 00:00:00 
... 
98 2016-05-01 01:37:00 20 2016-05-01 01:30:00 
99 2016-05-01 01:38:00 29 2016-05-01 01:30:00 
100 2016-05-01 01:39:00 37 2016-05-01 01:30:00 

現在,通過新的分組列aggregate,使用sum作爲聚合函數:

dat.summary = aggregate(count ~ by15, FUN=sum, data=dat) 
    by15 count 
1 2016-05-01 00:00:00 312 
2 2016-05-01 00:15:00 395 
3 2016-05-01 00:30:00 341 
4 2016-05-01 00:45:00 318 
5 2016-05-01 01:00:00 349 
6 2016-05-01 01:15:00 397 
7 2016-05-01 01:30:00 341 

dplyr

library(dplyr) 

dat.summary = dat %>% group_by(by15=cut(time, "15 min")) %>% 
    summarise(count=sum(count)) 

data.table

library(data.table) 

dat.summary = setDT(dat)[ , list(count=sum(count)), by=cut(time, "15 min")] 

UPDATE:要回答的註釋,對於這種情況下的每個分組時間間隔的結束點是as.POSIXct(as.character(dat$by15)) + 60*15 - 1。換句話說,分組間隔的終點是從間隔開始15分鐘減1秒。我們添加60 * 15 - 1,因爲POSIXct以秒爲單位。 as.POSIXct(as.character(...))是因爲cut返回一個因子,這只是將其轉換回日期時間,以便我們可以對其進行數學運算。

如果您希望在下一個時間間隔(而不是最近的時間間隔)之前將結束點指定爲最接近的分鐘,則可以輸入as.POSIXct(as.character(dat$by15)) + 60*14

例如,如果您不知道中斷間隔,例如因爲您選擇了中斷數並讓R選擇間隔,則可以通過執行max(unique(diff(as.POSIXct(as.character(dat$by15))))) - 1找到要添加的秒數。

+1

這是一個偉大的答案!您如何有效地找到每個間隔(大部分)的端點? –

+0

完美答案!非常感謝你! – adrian1121

+0

再次感謝您的精彩回答! –

0

切割方法非常方便,但數據幀較大。下面的方法是約1000倍,比切割方法快

#  Function: Truncate (floor) POSIXct to time interval (specified in seconds) 
    #  Author: Stephen McDaniel @ PowerTrip Analytics 
    #  Date : 2017MAY 
    # Copyright: (C) 2017 by Freakalytics, LLC 
    #  License: MIT 

    floor_datetime <- function(date_var, floor_seconds = 60, 
     origin = "1970-01-01") { # defaults to minute rounding 
    if(!is(date_var, "POSIXct")) stop("Please pass in a POSIXct variable") 
    if(is.na(date_var)) return(as.POSIXct(NA)) else { 
     return(as.POSIXct(floor(as.numeric(date_var)/
      (floor_seconds))*(floor_seconds), origin = origin)) 
    } 
    } 

樣本輸出(帶有400K記錄測試。):

test <- data.frame(good = as.POSIXct(Sys.time()), 
    bad1 = as.Date(Sys.time()), 
    bad2 = as.POSIXct(NA)) 

test$good_15 <- floor_datetime(test$good, 15 * 60) 
test$bad1_15 <- floor_datetime(test$bad1, 15 * 60) 
Error in floor_datetime(test$bad, 15 * 60) : 
    Please pass in a POSIXct variable 
test$bad2_15 <- floor_datetime(test$bad2, 15 * 60) 

test 

         good  bad1 bad2    good_15 bad2_15 
    1 2017-05-06 13:55:34.48 2017-05-06 <NA> 2007-05-06 13:45:00 <NA> 
相關問題