You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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))

当前结果与预期正确值对比如下(需求:无高温日时重置计数):

YearMonthDayTemperaturep90HDCDCD (correct)
199211320.6821.95000
199211420.8221.95000
199211521.6621.95000
199211622.0421.95111
199211723.3221.95122
199211823.9121.95123
199211923.5421.95124
199212021.8921.95000
199212121.9521.95000

问题原因

原代码中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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.01 13:24:52