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

如何在分组DataFrame中用rle函数计算年度连续降温最长天数

问题描述

我有如下结构的DataFrame(df):

df <- data.frame(prox)

数据样例:

year month   day Tmean
  <dbl> <dbl> <dbl> <dbl>
1  1956     1     1 13.5
2  1956     1     2 11.9
3  1956     1     3  9.71
4  1956     1     4  8.65
5  1956     1     5  4.51
6  1956     1     6  4.64
7  1956     1     7  6.66
8  1956     1     8  7.48
9  1956     1     9  5.56
10 1956     1    10  7.51

我需要找出连续降温天数的最大值。针对单一年份,已实现功能,代码如下(运行正常):

y <- rle(diff(df$Tmean) < 0) 
max(y$lengths[y$values], na.rm=TRUE) 
# [1] 6

但现在需要按年份(1956、1957……)分别计算该值,尝试用group_by时遇到问题:rle返回list类型,且当前代码未正确分组计算:

df %>% group_by(year) %>%   
    summarise(x=list(rle(diff(df$Tmean) < 0)))  

运行结果仅把全局rle结果按年份重复存储,并非分组计算:

year    x  
   <dbl> <list> 
1  1956 <rle>  
2  1957 <rle>
3  1958 <rle> 
解决方法

你之前的代码核心问题是:group_by后使用df$Tmean会直接调用全局数据,而非当前分组的子集。下面提供两种可行的分组计算方案:

方案1:结合dplyr与rle直接计算

直接在分组的summarise块内完成rle分析和最大值提取,无需存储list对象:

library(dplyr)

df %>%
  group_by(year) %>%
  summarise(max_consec_cooling = {
    # 计算当前年份内每日是否比前一天降温
    cool_seq <- diff(Tmean) < 0
    # 对降温序列做游程编码分析
    rle_out <- rle(cool_seq)
    # 提取所有降温段的长度,取最大值(无降温时na.rm=TRUE会返回-Inf,可替换为0)
    max_len <- max(rle_out$lengths[rle_out$values], na.rm = TRUE)
    # 处理全年无降温的情况,将-Inf转为0
    ifelse(is.infinite(max_len), 0, max_len)
  })

方案2:用窗口函数标记连续降温段(无需rle)

如果不想依赖rle,可以通过窗口函数给连续降温的天数分配分组ID,再统计每组长度的最大值:

library(dplyr)

df %>%
  group_by(year) %>%
  mutate(
    # 判断当天是否比前一天降温(第一天无前置数据,标记为NA)
    is_cooling = Tmean < lag(Tmean),
    # 给连续降温的片段分配唯一ID:每当降温中断(或第一天),分组ID+1
    cool_group = cumsum(!is_cooling | is.na(is_cooling))
  ) %>%
  # 仅保留降温的天数
  filter(is_cooling) %>%
  # 按年份和降温段分组,统计每个段的长度
  group_by(year, cool_group) %>%
  summarise(segment_length = n()) %>%
  # 按年份取最大的降温段长度
  group_by(year) %>%
  summarise(max_consec_cooling = max(segment_length, na.rm = TRUE)) %>%
  # 处理全年无降温的情况,将NA转为0
  mutate(max_consec_cooling = ifelse(is.na(max_consec_cooling), 0, max_consec_cooling))

结果说明

两种方案都会返回按年份分组的最大连续降温天数,例如1956年的结果为6,与单年份计算结果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:37:46