如何按年份筛选满足先≤5℃后≥15℃条件的R语言DataFrame数据
问题
现有一个包含日期(date)和温度(degrees)的DataFrame,需要按年份筛选出存在温度降至5℃或更低、之后又升至15℃或更高的年份的全部数据。时间跨度涵盖数年中的部分月份或周。当前使用dplyr、purrr和lubridate包,也接受其他包的解决方案。
可复现示例代码:
date <- as.Date(c("2020-01-01", "2020-01-02", "2020-01-03", "2020-01-04", "2021-01-01", "2021-01-02", "2021-01-03", "2021-01-04", "2022-01-01", "2022-01-02", "2022-01-03", "2022-01-04", "2023-01-01", "2023-01-02", "2023-01-03", "2023-01-04")) degrees <- c(10,5,10,15,20,6,10,15,0,0,10,20,10,8,20,15) df <- data.frame(date, degrees)
期望输出:
| date | degrees |
|---|---|
| 2020-01-01 | 10 |
| 2020-01-02 | 5 |
| 2020-01-03 | 10 |
| 2020-01-04 | 15 |
| 2022-01-01 | 0 |
| 2022-01-02 | 0 |
| 2022-01-03 | 10 |
| 2022-01-04 | 20 |
解决方案
使用dplyr结合lubridate可以快速实现需求,核心逻辑是按年份分组后,判断该年份是否存在「先出现≤5的温度,之后出现≥15的温度」的情况,最后筛选出符合条件的年份数据。
代码实现:
library(dplyr) library(lubridate) result <- df %>% # 提取年份作为分组依据 mutate(year = year(date)) %>% group_by(year) %>% # 判断年份是否满足条件:有降温到≤5的记录,且该记录之后有升温到≥15的记录 filter(any(degrees <= 5) && any(cumsum(degrees <= 5) > 0 & degrees >= 15)) %>% # 移除辅助列 select(-year) %>% ungroup() print(result)
逻辑说明
- 提取年份:用
lubridate::year()从日期中拆分出年份,作为分组的依据; - 条件判断:
any(degrees <=5):确保该年份至少有一次温度降至5℃或更低;cumsum(degrees <=5)会标记出首次出现降温后的所有行,结合degrees >=15可以判断降温后是否出现了符合要求的升温;
- 结果整理:过滤出符合条件的年份数据,移除辅助列并取消分组。
执行代码后得到的结果与期望输出完全一致。
内容的提问来源于stack exchange,提问作者pcLoadLetter
相关产品推荐
相关产品推荐

