【问题标题】:R - Calculate sum within date range using zooR - 使用动物园计算日期范围内的总和
【发布时间】:2017-01-17 02:20:52
【问题描述】:

假设我有一个包含十年每日温度数据(以摄氏度为单位)的数据框,如下所示:

mydf <- data.frame(Date = seq(as.Date("2001/1/1"), as.Date("2010/12/31"), by = "day"), Temp = runif(3652, 0, 40))

我正在尝试计算植物的生长期天数。这就是它的工作原理:在一个日期范围内,我需要整合每日温度和基准温度之间的差异,比如 10 摄氏度。为了更难,日期范围跨越多年。例如,我需要计算时间序列中所有年份从 11 月 1 日到 3 月 31 日之间的生长期。就“算法”而言,逻辑是这样的:

t_base <- 10

for (each day between nov 1st and mar 31st) {
  sum (Temp - t_base)
}

如何使用 zoo 包做到这一点?

【问题讨论】:

    标签: r date sum range zoo


    【解决方案1】:

    请注意,"yearmon" 类变量的形式为 year + frac,其中 frac 为 0 表示一月,1/12 表示二月,2/12 表示三月,等等。ym 下面是一个 "yearmon" 向量对应于Date,只是我们增加了两个月。然后ym被拆分为年份y(季节结束年份)和月份m(其中月份为0,表示季节的第一个月, 1 表示第二个月,...,4 表示季节的第 5 个月和最后一个月,非季节月份的数字更高)。in.seas 对于 11 月、12 月、1 月、2 月或 3 月的数据点为 TRUE(其中对应m &lt;= 4)。最后使用ave计算具有相同季节结束年份的日期之间的累计和或aggregate计算总和。

    library(zoo)
    
    z <- read.zoo(mydf)
    ym <- as.numeric(as.yearmon(index(z)) + 2/12)
    y <- floor(ym) # year of date's season end or this year if not in season
    m <- round(12 * (ym - y))  # month Nov = 0, Dec = 1, Jan = 2, Feb = 3, Mar = 4, ...
    in.seas <- m <= 4
    Cum <- ave(z[in.seas], y[in.seas], FUN = function(x) cumsum(x - t_base))
    

    或者只是得到每个季节的总和:

    Sum <- aggregate(z[in.seas], y[in.seas], function(x) sum(x - t_base))
    

    请注意,fortify.zoo(x) 会将动物园对象 x 转换回数据框(如果有必要)。

    【讨论】:

    • 已将评论移至回答。
    • 酷,感谢您的回答,并非常感谢zoo 包。
    猜你喜欢
    • 2021-05-27
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    • 1970-01-01
    • 2020-01-13
    • 1970-01-01
    相关资源
    最近更新 更多