如何用dplyr筛选每年温度局部最小值后的天数?
使用dplyr实现按年份剔除温度局部最小值前的所有数据
示例数据集
原始数据集通过tribble创建:
tribble( ~year, ~day, ~temp, 2020, 90, 4, 2020, 91, 3, 2020, 92, 0, 2020, 93, 2, 2020, 94, 5, 2021, 90, 2, 2021, 91, 0, 2021, 92, 2, 2021, 93, 4, 2021, 94, 6 )
需求说明
按年份分组,找到每组中温度局部最小值(示例中为0)所在的行,剔除该行之前的所有数据,仅保留该行之后的记录,最终得到结果:
year day temp <dbl> <dbl> <dbl> 1 2020 93 2 2 2020 94 5 3 2021 92 2 4 2021 93 4 5 2021 94 6
解决方案(dplyr实现)
针对全局最小值场景
如果需求中的"局部最小值"是指该年份的温度全局最小值,直接用以下代码即可:
library(dplyr) df %>% group_by(year) %>% filter(row_number() > which(temp == min(temp))[1]) %>% ungroup()
代码说明
group_by(year):按年份分组,保证每个年份的数据独立处理row_number() > which(temp == min(temp))[1]:min(temp)获取当前年份的温度最小值which(temp == min(temp))定位所有等于最小值的行位置,[1]取第一个出现的最小值位置(若有多个最小值,仅以第一个为分界点)- 筛选行号大于该位置的记录,即保留最小值所在行之后的所有数据
ungroup():取消分组,恢复普通数据框格式
针对真正局部极小值场景
如果"局部最小值"是指比前后两天温度都低的点,可通过lead()和lag()判断:
df %>% group_by(year) %>% mutate(is_local_min = temp < lag(temp, default = Inf) & temp < lead(temp, default = Inf)) %>% filter(row_number() > which(is_local_min)[1]) %>% select(-is_local_min) %>% ungroup()
代码说明
mutate(is_local_min = ...):标记出真正的局部极小值(比前一天和后一天温度都低)- 后续逻辑和全局最小值场景一致,以第一个局部极小值为分界点筛选数据
内容的提问来源于stack exchange,提问作者UlvHare
相关产品推荐
相关产品推荐

