R - 使用动物园计算日期范围内的总和
R - Calculate sum within date range using zoo
假设我有一个包含十年每日温度数据(以摄氏度为单位)的数据框,如下所示:
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 日之间的生长天数。就 "algorithm" 而言,逻辑是这样的:
t_base <- 10
for (each day between nov 1st and mar 31st) {
sum (Temp - t_base)
}
如何使用 zoo 包执行此操作?
请注意 "yearmon
" class 变量的形式为 year + frac,其中 frac 为 0 表示 1 月,1/12 表示 2 月,2/12 表示 3 月,等等。下面 ym
是一个 "yearmon"
向量对应于 Date
除了我们增加了两个月。然后 ym
被拆分成 y
年(季末年)和月份 m
(当季的第一个月为 0,第二个月为 1,...,第 5 个月和最后一个月为 4,非当季月份的数字更大)。in.seas
对于11月、12月、1月、2月或3月的那些数据点为TRUE(对应于m <= 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
转换回数据框。
假设我有一个包含十年每日温度数据(以摄氏度为单位)的数据框,如下所示:
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 日之间的生长天数。就 "algorithm" 而言,逻辑是这样的:
t_base <- 10
for (each day between nov 1st and mar 31st) {
sum (Temp - t_base)
}
如何使用 zoo 包执行此操作?
请注意 "yearmon
" class 变量的形式为 year + frac,其中 frac 为 0 表示 1 月,1/12 表示 2 月,2/12 表示 3 月,等等。下面 ym
是一个 "yearmon"
向量对应于 Date
除了我们增加了两个月。然后 ym
被拆分成 y
年(季末年)和月份 m
(当季的第一个月为 0,第二个月为 1,...,第 5 个月和最后一个月为 4,非当季月份的数字更大)。in.seas
对于11月、12月、1月、2月或3月的那些数据点为TRUE(对应于m <= 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
转换回数据框。