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

如何使用dplyr实现分阈值的寒潮与强寒潮判定逻辑

dplyr 寒潮等级判定实现方案

核心逻辑是先计算实际气温与常年均值的差值,再用dplyr::case_when()按规则分场景判定等级,比嵌套ifelse逻辑更清晰易维护。
首先修正原有常年均值计算的小问题:原代码中按日分组后对所有列求均值,会导致日期列Date被无意义平均,调整后完整实现代码如下:

library(tidyverse)
library(zoo)

set.seed(123)
df <- data.frame("Date"= seq(from = as.Date("1970-1-1"), to = as.Date("2000-12-31"), by = "day"),
                 "Station1" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 10, 30),
                 "Station2" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 11, 29),
                 "Station3" = runif(length(seq.Date(as.Date("1970-1-1"), as.Date("2000-12-31"), "days")), 8, 28))

# 计算常年最低气温(按儒略日分组统计各站点多年均值)
df_summarise_all <- df %>% 
  as_tibble() %>%
  mutate(day = format(Date, format='%m-%d')) %>% 
  select(-Date) %>% # 移除不需要求平均的日期列
  group_by(day) %>%
  summarise(across(everything(), mean, na.rm = TRUE)) %>% # 仅对站点列求均值
  pivot_longer(cols = -day, names_to = "Stations", values_to = "mean_MinT")

# 识别寒潮等级
df_out <- df %>%
  as_tibble() %>%
  mutate(day = format(Date, format='%m-%d')) %>%
  pivot_longer(cols = -c(Date, day), names_to = "Stations", values_to = "MinT") %>%
  left_join(df_summarise_all, by = c("day", "Stations")) %>%
  # 计算气温距平:实际气温 - 常年同期均值
  mutate(temp_delta = MinT - mean_MinT,
         # 按规则判定寒潮等级
         coldwave_level = case_when(
           # 常年最低温≥10℃的场景
           mean_MinT >= 10 & temp_delta <= -7 ~ "强寒潮",
           mean_MinT >= 10 & temp_delta <= -5 & temp_delta >= -6 ~ "寒潮",
           # 常年最低温<10℃的场景
           mean_MinT < 10 & temp_delta <= -6 ~ "强寒潮",
           mean_MinT < 10 & temp_delta <= -4 & temp_delta >= -5 ~ "寒潮",
           # 其余情况归为无寒潮
           TRUE ~ NA_character_
         ),
         # 如需单独的逻辑判定列可额外生成
         is_coldwave = !is.na(coldwave_level),
         is_strong_coldwave = coldwave_level == "强寒潮"
  )

关键说明

  • case_when()按优先级匹配条件,符合第一个满足的条件就返回对应值,不用写多层嵌套判断
  • 先计算距平temp_delta可以避免重复计算,代码可读性更高
  • 如果你需要判断连续多日降温的寒潮规则,只需要调整zoo::rollapplyr的宽度参数即可,当前单日判定无需用到滑动窗口函数

内容的提问来源于stack exchange,提问作者UseR10085

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 23:06:05