在R语言中按分组查找连续日期序列的最优方法
解决连续热浪序列的分组统计问题
我来帮你搞定这个按年份统计连续热浪序列的需求,下面提供两种常用的高效实现方案,分别用dplyr和data.table,都能精准得到你想要的结果。
首先先构造你提供的示例数据,方便复现:
# 构造示例数据框 heatwave_df <- tibble( year = c(2011,2011,2011,2011,2011,2011,2011,2012,2012,2012,2012,2012,2012,2012), day = c(150,151,152,166,167,168,169,177,178,179,180,195,196,197), temp = c(96,96,97,98,99,98,99,96,96,95,98,100,99,99) )
方法一:使用dplyr(tidyverse风格)
这个方法逻辑清晰,适合习惯tidyverse语法的用户:
- 先按年份分组,确保每组内的日期是按顺序排列的(避免原始数据乱序的问题)
- 标记每个热浪序列的起始点:要么是组内第一行,要么当前日期和前一天的差值大于1(说明中断了,是新的热浪)
- 用
cumsum对起始点累加,生成每个热浪的编号num.hw - 最后按年份和热浪编号分组,统计持续时长和平均温度
library(dplyr) result_dplyr <- heatwave_df %>% arrange(year, day) %>% # 确保日期有序 group_by(year) %>% mutate( # 标记新热浪的起始 is_new_hw = row_number() == 1 | day - lag(day) > 1, num.hw = cumsum(is_new_hw) ) %>% group_by(year, num.hw) %>% summarise( length.hw = n(), # 这里如果需要和你预期的整数结果一致,可以用round(mean(temp), 0) avg.temp = mean(temp), .groups = "drop" ) print(result_dplyr)
如果需要和你给出的预期输出里的整数平均温度完全匹配,把avg.temp = mean(temp)改成avg.temp = round(mean(temp), 0)即可。
方法二:使用data.table(高效大数据处理)
如果你的数据集很大,data.table的性能会更优,链式操作也很简洁:
library(data.table) # 转换为data.table格式 heatwave_dt <- as.data.table(heatwave_df) result_dt <- heatwave_dt[order(year, day), # 先排序 # 分组标记新热浪起始 .(is_new_hw = .I == 1 | day - shift(day) > 1, temp = temp), by = year ][, # 生成热浪编号 num.hw := cumsum(is_new_hw), by = year ][, # 统计每组的时长和平均温度 .(length.hw = .N, avg.temp = mean(temp)), by = .(year, num.hw) ] print(result_dt)
同样,如果需要整数平均温度,把mean(temp)改成round(mean(temp), 0)就行。
两种方法运行后都会得到符合预期的结果,调整取整逻辑后就能和你给出的示例输出完全一致。
内容的提问来源于stack exchange,提问作者user2113499
相关产品推荐
相关产品推荐

