【问题标题】:Aggregating days on an annual basis in R time series在 R 时间序列中每年汇总天数
【发布时间】:2016-09-12 22:56:02
【问题描述】:

我有一个多年 (1985-2010) 时间序列的每日数据,我想以 8 天为间隔进行汇总。问题是我对分析年度结果很感兴趣,所以每年的第一个间隔应该从 1 月 1 日开始。

如果我构造一个示例动物园对象:

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 天获得时间标记数据?感谢您的帮助!

【问题讨论】:

    标签: r time-series


    【解决方案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 动物园对象。

    【讨论】:

    • 谢谢!这让我走上了正确的道路。要申请所有年份(而不仅仅是上面的“1985”),我使用了 lapply:a.list &lt;- 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 选项会。
    【解决方案2】:

    这可能不是最佳答案,但您可以提取第二种方法的名称,然后将其分配给您的 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)
    

    【讨论】:

    • 这也很有效!在do.call 命令期间,名称被去除了“日期”格式,但将结果转换为动物园对象很容易:a8.mean.zoo &lt;- zoo(a8.mean, order.by = as.Date(names(a8.mean))) 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 2022-06-27
    • 2022-01-07
    • 2020-01-15
    相关资源
    最近更新 更多