2016-05-17 123 views
1

我有一個多年(1985-2010)時間序列的日常數據,我希望以8天的間隔彙總。問題是,我很感興趣,分析年度業績,所以每年的第一區間應在1月1日在R時間序列中每年彙總天數

開始如果你建造一個例子動物園對象:

library(zoo) 
indices <- seq.Date(as.Date("1985-01-01"), as.Date("1988-12-31"), by = 'day') 
a.zoo <- zoo(rnorm(length(indices)), order.by = indices) 

head(a.zoo) 
1985-01-01 1985-01-02 1985-01-03 1985-01-04 1985-01-05 1985-01-06 
0.47454560 -1.10429098 -1.27926702 0.46199385 -0.12975014 0.03752185 

那麼我就可以rollapply使用以獲得部分途徑:

rollapply(a.zoo, 8, by=8, by.column=FALSE, FUN=function(x) mean(x), align = "left") 

但是年份之間沒有區別,所以第一個年度間隔的開始日期各不相同。如果我變換動物園對象轉換爲數據幀我可以用一個plyr命令逐年應用功能:

library(plyr) 
a.df <- data.frame(date = time(a.zoo), 
        data = a.zoo, 
        check.names = F, 
        row.names = NULL) 
a.8 <- dlply(a.df, .(format(date, "%Y")), 
      function(x) {split(x$data, ceiling(seq_along(x$data)/8))}) 
a8.mean <- rapply(a.8, mean, na.rm = T) 

head(a8.mean) 
    1985.1  1985.2  1985.3  1985.4  1985.5  1985.6 
-0.2744355 0.3103211 0.2057675 -0.1537141 0.6807115 -0.1581474 

,但我失去的最新信息。對於如何調整一種方法或其他方法(或者可以提供一個新的更精彩的想法),是否有人有任何建議,以便每年從1月1日起每隔8天結束一次帶有時間標記的數據?謝謝你的幫助!

回答

1

我對此解決方案使用了此SO回答。通過一年基本上劃分zoo對象:

a.yr = tapply(a.zoo, format(index(a.zoo), "%Y"), c) 

然後申請rollapply你在做,每年可爲。

rollapply(a.yr$`1985`, 8, by=8, by.column=FALSE, FUN=function(x) mean(x), align = "left") 

然後,您可以merge動物園的對象。

+1

謝謝!這使我走上了正軌。爲了適用於所有年份(而不僅僅是上面的'1985'),我使用了lapply:'a.list < - lapply(a.yr,function(x)zoo(rollapply(x,8,by = 8,by.column = FALSE,FUN = function(y)mean(y),align =「left」)))'然後'do.call(「rbind」,a.list)'。請注意,這與下面的解決方案之間唯一的區別在於'rollapply'不會返回任何小於指定元素數量(本例中爲8)的區間的值,而dataframe選項則會這樣。 – Jaywalker

1

這可能不是最好的答案,但你可以爲你的第二個方法提取的名稱,然後將其分配給您的a8.mean結果

a8.name <- (dlply(a.df, .(format(date, "%Y")), function(x) x$date[seq_along(x$date) %% 8 == 1])) 
names(a8.mean) <- do.call(c, a8.name) 
+0

這也適用!在'do.call'命令中,名稱被刪除了「日期」格式,但將結果轉換爲動物園對象很容易:a8.mean.zoo < - 動物園(a8.mean,order.by = as。日期(名字(a8.mean)))'非常感謝! – Jaywalker