2014-03-05 104 views
3

我的問題是將每1分鐘收集的數據彙總爲5分鐘的平均值。將1分鐘的數據彙總爲5分鐘的平均數據

DeviceTime   Concentration 
6/20/2013 11:13  
6/20/2013 11:14 
6/20/2013 11:15 
6/20/2013 11:16 
6/20/2013 11:17 
6/20/2013 11:18 
6/20/2013 11:19 
6/20/2013 11:20 
6/20/2013 11:21 
6/20/2013 11:22 
6/20/2013 11:23 
6/20/2013 11:24 
6/20/2013 11:25 
6/20/2013 11:26 
6/20/2013 11:27 
6/20/2013 11:28 

...

我想要的結果是這樣的:

DeviceTime    Concentration 
6/20/2013 11:15 
6/20/2013 11:20 
6/20/2013 11:25 
6/20/2013 11:30 
6/20/2013 11:35 
... 

5分鐘的平均僅僅是簡單的平均值的濃度在過去的五分鐘。

+0

'cut'可以將日期/時間對象的中斷設置爲比如說「5分鐘」... – A5C1D2H2I1M1N2O1R2T1

+0

[How to round a time?]的可能重複(http://stackoverflow.com/questions/ 17108515/how-to-round-a-time) –

+0

[每小時步驟值的15分鐘步驟的聚合值]的可能重複(http://stackoverflow.com/questions/17389533/aggregate-values-of-15-分鐘步驟到小時值的步驟) – agstudy

回答

8

使用dplyr包並假設,您的數據存儲在名爲df的數據幀:

require(dplyr) 
df %>% 
    group_by(DeviceTime = cut(DeviceTime, breaks="5 min")) %>% 
    summarize(Concentration = mean(Concentration)) 
+1

語法看起來有點複雜:) – agstudy

+0

@agstudy我總是樂於接受建議: - > – lukeA

+0

作爲一個評論佈局它有點奇怪,但是你可以用這種方式簡化你的代碼lukeA。 (cutdown)(DeviceTime = cut(「5分鐘」))%。% 總結(濃度=平均值(濃度))' – Gianluca

12

如果數據不很好5分鐘掛鐘邊界上開始(如圖所示在示例數據– 11:13),請注意cut()將基於它找到的第一個時間戳創建斷點。這可能不是我們通常想要的。事實上,你的樣本輸出表明這不是你想要的。

這裏是cut()做:

df <- read.table(header=TRUE, sep=",", stringsAsFactors=FALSE, text=" 
DeviceTime,Concentration 
6/20/2013 11:13,1 
6/20/2013 11:14,1 
6/20/2013 11:15,2 
6/20/2013 11:16,2 
6/20/2013 11:17,2 
6/20/2013 11:18,2 
6/20/2013 11:19,2 
6/20/2013 11:20,3 
6/20/2013 11:21,3 
6/20/2013 11:22,3 
6/20/2013 11:23,3 
6/20/2013 11:24,3 
6/20/2013 11:25,4") 
df$DeviceTime <- as.POSIXct(df$DeviceTime, format="%m/%d/%Y %H:%M") 

cut(df$DeviceTime, breaks="5 min") 
[1] 2013-06-20 11:13:00 2013-06-20 11:13:00 2013-06-20 11:13:00 
[4] 2013-06-20 11:13:00 2013-06-20 11:13:00 2013-06-20 11:18:00 
[7] 2013-06-20 11:18:00 2013-06-20 11:18:00 2013-06-20 11:18:00 
[10] 2013-06-20 11:18:00 2013-06-20 11:23:00 2013-06-20 11:23:00 
[13] 2013-06-20 11:23:00 

means <- aggregate(df["Concentration"], 
        list(fiveMin=cut(df$DeviceTime, "5 mins")), 
        mean) 
means 
       fiveMin Concentration 
1 2013-06-20 11:13:00  1.600000 
2 2013-06-20 11:18:00  2.600000 
3 2013-06-20 11:23:00  3.333333 

注意的means(在十一點13分零零秒進入)第一行是第5行的df,其具有11:13倍的平均到11:17 - 也就是直到下一個11:18的切割/折斷點之前。

你會得到與dplyr(即@ lukeA的答案)相同的結果,如果你使用cut()

df %>% 
    group_by(DeviceTime = cut(DeviceTime, breaks="5 min")) %>% 
    summarize(Concentration = mean(Concentration)) 
Source: local data frame [3 x 2] 

      DeviceTime Concentration 
1 2013-06-20 11:13:00  1.600000 
2 2013-06-20 11:18:00  2.600000 
3 2013-06-20 11:23:00  3.333333 

的XTS包似乎通過掛鐘時間打破:

require(xts) 
df.xts <- xts(df$Concentration, df$DeviceTime) 
means.xts <- period.apply(df.xts, endpoints(df.xts, "mins", k=5), mean) 
means.xts 
        [,1] 
2013-06-20 11:14:00 1 
2013-06-20 11:19:00 2 
2013-06-20 11:24:00 3 
2013-06-20 11:25:00 4 

時間值始終是最後一次在5分鐘窗口中找到的條目。你可以用align.time()圓的時間索引列了下一個5分鐘的邊界,如果你想報告期結束的時間:

means.rounded <- align.time(means.xts, 5*60) 
means.rounded 
        [,1] 
2013-06-20 11:15:00 1 
2013-06-20 11:20:00 2 
2013-06-20 11:25:00 3 
2013-06-20 11:30:00 4 

您也可以四捨五入,如果您要報案時期的開始時間。但是,你需要先定義你自己的功能(這是我在Cross Validated找到):

align.time.down = function(x,n) { 
    index(x) = index(x) - n 
    align.time(x,n) 
} 
means.rounded.down <- align.time.down(means.xts, 5*60) 
means.rounded.down 
        [,1] 
2013-06-20 11:10:00 1 
2013-06-20 11:15:00 2 
2013-06-20 11:20:00 3 
2013-06-20 11:25:00 4 

另一種解決方案,即不使用XTS包,而是floor(),如下:

df$DeviceTimeFloor <- as.POSIXct(floor(as.numeric(df$DeviceTime)/(5 * 60)) * (5 * 60), origin='1970-01-01') 
meansFloor <- aggregate(Concentration ~ DeviceTimeFloor, df, mean) 
meansFloor 
     DeviceTimeFloor Concentration 
1 2013-06-20 11:10:00    1 
2 2013-06-20 11:15:00    2 
3 2013-06-20 11:20:00    3 
4 2013-06-20 11:25:00    4 

我寧願報告5分鐘間隔的開始時間– floor()對此很有幫助。因爲如果我要按小時報告彙總數據,我希望2013-06-20 11:00:00的時間戳包含時間段11:00:00 - 11:59:59而非10:00:00的數據 - 10:59:59。

如果您希望報告間隔的結束時間,可以使用ceiling()而不是floor()。但請注意,時間戳11:01 - 11:05將由ceiling()轉換爲(並因此分組)到11:05。相反,floor()將11:00 - 11:04轉換爲11:00。

所以他們每個人都有一組不同的觀察值。 xts包將對與floor()相同的一組觀測進行分組,但它會報告上一次觀測的最後一個時間戳。

相關問題