如何在R语言中统计连续高温日的天数?
连续高温日计数的正确实现方法
问题背景
我已创建高温日指标hd(Heat Day),当日均温tmean超过90百分位数p90时赋值为1,否则为0;同时初始化计数变量cd,初始逻辑与hd一致:
temp <- temp %>% mutate(hd=if_else(tmean>p90,1,0), cd=if_else(tmean>p90,1,0))
随后尝试用以下代码更新cd以统计连续高温天数,但未得到预期结果:
temp <- temp %>% mutate(cd=if_else(hd==1, cd + lag(cd, default = 0), 0))
当前结果与预期正确值对比如下(需求:无高温日时重置计数):
| Year | Month | Day | Temperature | p90 | HD | CD | CD (correct) |
|---|---|---|---|---|---|---|---|
| 1992 | 1 | 13 | 20.68 | 21.95 | 0 | 0 | 0 |
| 1992 | 1 | 14 | 20.82 | 21.95 | 0 | 0 | 0 |
| 1992 | 1 | 15 | 21.66 | 21.95 | 0 | 0 | 0 |
| 1992 | 1 | 16 | 22.04 | 21.95 | 1 | 1 | 1 |
| 1992 | 1 | 17 | 23.32 | 21.95 | 1 | 2 | 2 |
| 1992 | 1 | 18 | 23.91 | 21.95 | 1 | 2 | 3 |
| 1992 | 1 | 19 | 23.54 | 21.95 | 1 | 2 | 4 |
| 1992 | 1 | 20 | 21.89 | 21.95 | 0 | 0 | 0 |
| 1992 | 1 | 21 | 21.95 | 21.95 | 0 | 0 | 0 |
问题原因
原代码中mutate是对整列批量计算的,lag(cd)调用的是初始的cd值,而非前一行更新后的cd值,因此从第三天连续高温日开始,无法正确累加计数。
正确实现方案
方案1:基于分组的计数(仅用dplyr)
先给连续的高温日生成分组标签,再在每个分组内逐行计数:
library(dplyr) # 第一步:创建hd指标 temp <- temp %>% mutate(hd = if_else(tmean > p90, 1, 0)) # 第二步:生成连续高温分组,再计算连续天数 temp <- temp %>% # 每次hd从0切换到1时,生成新分组 mutate(group = cumsum(hd != lag(hd, default = 0))) %>% # 仅在高温日分组内计数,非高温日设为0 mutate(cd = if_else(hd == 1, row_number() - first(row_number()) + 1, 0)) %>% # 可选:删除临时的group列 select(-group)
方案2:用accumulate逐行计算(需purrr包)
利用purrr::accumulate函数逐行迭代,根据前一天的计数更新当天值:
library(dplyr) library(purrr) temp <- temp %>% mutate(hd = if_else(tmean > p90, 1, 0)) %>% mutate(cd = accumulate(hd, ~ if_else(.y == 1, .x + 1, 0), .init = 0) %>% tail(-1))
结果验证
运行上述任意方案后,cd列将得到预期的正确值:连续高温日从1开始逐天累加,非高温日自动重置为0。
内容的提问来源于stack exchange,提问作者VonFer
相关产品推荐
相关产品推荐

