R - 跨年的累计和
R - Cumulative sum that crosses years
我有一个数据 table,每天的降水量测量值如下所示:
library(data.table)
pr <- data.table(date=seq(as.Date("2000-01-01"), as.Date("2004-12-31"), by="1 day"),
precip=runif(1827, 0, 20))
date precip
1: 2000-01-01 8.390553
2: 2000-01-02 11.753791
3: 2000-01-03 1.346553
4: 2000-01-04 15.130108
5: 2000-01-05 2.027514
---
1823: 2004-12-27 17.550784
1824: 2004-12-28 7.054898
1825: 2004-12-29 4.458190
1826: 2004-12-30 6.989788
1827: 2004-12-31 2.257400
我想获得此数据集中所有生长季节的累积降水量,其中生长季节定义为 9 月到 4 月之间的时间段。
因此,结果数据 table 应包含 Sep2000 - Apr2001、Set2001 - Apr 2002 等的累计总和。
如何实现?
4 月底距年初还有 120 天。如果您从 date
列中的所有条目中减去 120 天以创建一个 pseudodate
列,那么您生长期中每一天的 pseudodate
将移至上一年。由于从 9 月 1 日减去 120 天得到同年 5 月 4 日,因此 5 月 4 日之前的任何 pseudodate
都将处于 non-growing 期间,并且该日期或之后直到年底的任何内容都必须是在当年九月开始的生长期。通过这种方法,我们可以很容易地根据是否处于生长期,并根据生长期开始的年份来标记每个实际日期。
然后我们需要做的就是过滤掉不在生长期的日期,group_by
生长期开始的那一年,然后在 [=17= 上执行 cumsum
] 专栏:
library(dplyr)
library(lubridate)
pr %>% mutate(pseudodate = date - days(120),
is_growing = yday(pseudodate) > 125,
season_beginning = year(pseudodate)) %>%
filter(is_growing) %>%
mutate(cum_precip = cumsum(precip)) %>%
select(date, precip, season_beginning, cum_precip)
#> date precip season_beginning cum_precip
#> 1: 2000-01-01 17.694152 1999 17.69415
#> 2: 2000-01-02 6.066319 1999 23.76047
#> 3: 2000-01-03 4.793192 1999 28.55366
#> 4: 2000-01-04 15.753112 1999 44.30678
#> 5: 2000-01-05 12.253172 1999 56.55995
#> ---
#> 1198: 2004-12-27 8.983804 2004 11490.72677
#> 1199: 2004-12-28 6.740315 2004 11497.46709
#> 1200: 2004-12-29 3.899960 2004 11501.36705
#> 1201: 2004-12-30 6.357432 2004 11507.72448
#> 1202: 2004-12-31 3.950666 2004 11511.67515
当然,由于这个示例数据集从 1 月 1 日开始,我们已经错过了那个季节的几个月的生长期,所以如果第一年也开始于一月.
这是一个data.table
方法。我们首先确定生长 (TRUE) / 收获 (FALSE) 季节,然后给每个季节一个 run-length id,最后按季节计数总结开始和结束日期以及总降水量。
set.seed(1)
pr <- data.table(
date=seq(as.Date("2000-01-01"), as.Date("2004-12-31"), by="1 day"),
precip=runif(1827, 0, 20)
)
pr[
, gr_season := !(month(date) %in% 5:8)
][
, season_count := rleidv(gr_season)
][
gr_season == TRUE, .(period = paste0(head(date, 1L), "/", tail(date, 1L)), precip = sum(precip)),
by = season_count
]
输出
season_count period precip
1: 1 2000-01-01/2000-04-30 1251.741
2: 3 2000-09-01/2001-04-30 2352.559
3: 5 2001-09-01/2002-04-30 2466.817
4: 7 2002-09-01/2003-04-30 2326.178
5: 9 2003-09-01/2004-04-30 2418.478
6: 11 2004-09-01/2004-12-31 1136.972
生长季节的每日累积量
pr[
, gr_season := !(month(date) %in% 5:8)
][
, season_count := rleidv(gr_season)
][
gr_season == TRUE, .(date = date, precip = cumsum(precip)),
by = season_count
]
输出
season_count date precip
1: 1 2000-01-01 5.310173
2: 1 2000-01-02 12.752651
3: 1 2000-01-03 24.209719
4: 1 2000-01-04 42.373874
5: 1 2000-01-05 46.407513
---
1208: 11 2004-12-27 1101.280221
1209: 11 2004-12-28 1112.926760
1210: 11 2004-12-29 1114.345408
1211: 11 2004-12-30 1125.758288
1212: 11 2004-12-31 1136.971833
我有一个数据 table,每天的降水量测量值如下所示:
library(data.table)
pr <- data.table(date=seq(as.Date("2000-01-01"), as.Date("2004-12-31"), by="1 day"),
precip=runif(1827, 0, 20))
date precip
1: 2000-01-01 8.390553
2: 2000-01-02 11.753791
3: 2000-01-03 1.346553
4: 2000-01-04 15.130108
5: 2000-01-05 2.027514
---
1823: 2004-12-27 17.550784
1824: 2004-12-28 7.054898
1825: 2004-12-29 4.458190
1826: 2004-12-30 6.989788
1827: 2004-12-31 2.257400
我想获得此数据集中所有生长季节的累积降水量,其中生长季节定义为 9 月到 4 月之间的时间段。
因此,结果数据 table 应包含 Sep2000 - Apr2001、Set2001 - Apr 2002 等的累计总和。
如何实现?
4 月底距年初还有 120 天。如果您从 date
列中的所有条目中减去 120 天以创建一个 pseudodate
列,那么您生长期中每一天的 pseudodate
将移至上一年。由于从 9 月 1 日减去 120 天得到同年 5 月 4 日,因此 5 月 4 日之前的任何 pseudodate
都将处于 non-growing 期间,并且该日期或之后直到年底的任何内容都必须是在当年九月开始的生长期。通过这种方法,我们可以很容易地根据是否处于生长期,并根据生长期开始的年份来标记每个实际日期。
然后我们需要做的就是过滤掉不在生长期的日期,group_by
生长期开始的那一年,然后在 [=17= 上执行 cumsum
] 专栏:
library(dplyr)
library(lubridate)
pr %>% mutate(pseudodate = date - days(120),
is_growing = yday(pseudodate) > 125,
season_beginning = year(pseudodate)) %>%
filter(is_growing) %>%
mutate(cum_precip = cumsum(precip)) %>%
select(date, precip, season_beginning, cum_precip)
#> date precip season_beginning cum_precip
#> 1: 2000-01-01 17.694152 1999 17.69415
#> 2: 2000-01-02 6.066319 1999 23.76047
#> 3: 2000-01-03 4.793192 1999 28.55366
#> 4: 2000-01-04 15.753112 1999 44.30678
#> 5: 2000-01-05 12.253172 1999 56.55995
#> ---
#> 1198: 2004-12-27 8.983804 2004 11490.72677
#> 1199: 2004-12-28 6.740315 2004 11497.46709
#> 1200: 2004-12-29 3.899960 2004 11501.36705
#> 1201: 2004-12-30 6.357432 2004 11507.72448
#> 1202: 2004-12-31 3.950666 2004 11511.67515
当然,由于这个示例数据集从 1 月 1 日开始,我们已经错过了那个季节的几个月的生长期,所以如果第一年也开始于一月.
这是一个data.table
方法。我们首先确定生长 (TRUE) / 收获 (FALSE) 季节,然后给每个季节一个 run-length id,最后按季节计数总结开始和结束日期以及总降水量。
set.seed(1)
pr <- data.table(
date=seq(as.Date("2000-01-01"), as.Date("2004-12-31"), by="1 day"),
precip=runif(1827, 0, 20)
)
pr[
, gr_season := !(month(date) %in% 5:8)
][
, season_count := rleidv(gr_season)
][
gr_season == TRUE, .(period = paste0(head(date, 1L), "/", tail(date, 1L)), precip = sum(precip)),
by = season_count
]
输出
season_count period precip
1: 1 2000-01-01/2000-04-30 1251.741
2: 3 2000-09-01/2001-04-30 2352.559
3: 5 2001-09-01/2002-04-30 2466.817
4: 7 2002-09-01/2003-04-30 2326.178
5: 9 2003-09-01/2004-04-30 2418.478
6: 11 2004-09-01/2004-12-31 1136.972
生长季节的每日累积量
pr[
, gr_season := !(month(date) %in% 5:8)
][
, season_count := rleidv(gr_season)
][
gr_season == TRUE, .(date = date, precip = cumsum(precip)),
by = season_count
]
输出
season_count date precip
1: 1 2000-01-01 5.310173
2: 1 2000-01-02 12.752651
3: 1 2000-01-03 24.209719
4: 1 2000-01-04 42.373874
5: 1 2000-01-05 46.407513
---
1208: 11 2004-12-27 1101.280221
1209: 11 2004-12-28 1112.926760
1210: 11 2004-12-29 1114.345408
1211: 11 2004-12-30 1125.758288
1212: 11 2004-12-31 1136.971833