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

如何在R的dplyr中为连续两年的数据创建分组ID?

为连续年份区间创建分组ID的dplyr解决方案

首先,你的示例数据集可以用以下代码复现:

library(tibble)
df <- tribble(
  ~cell, ~year, ~month, ~day_of_month, ~day_of_year, ~preliq_q, ~tsup_h_q, ~tinf_h_q, ~t_q,
  4, 2002, 2, 26, 57, 5.7, 12.1, 8.6, 10.2,
  4, 2002, 2, 27, 58, 5.1, 9.3, 5.3, 6.7,
  4, 2002, 2, 28, 59, 6.7, 8.7, 4.8, 6.2,
  4, 2003, 2, 26, 57, 0, 13.2, 3.7, 7.9,
  4, 2003, 2, 27, 58, 0, 16.4, 7.5, 10.7,
  4, 2003, 2, 28, 59, 5.6, 10, 7.2, 8.6,
  4, 2004, 2, 26, 57, 0.2, 2.8, 1, 1.5,
  4, 2004, 2, 27, 58, 1.2, 2.8, 0.5, 1.8,
  4, 2004, 2, 28, 59, 3.2, 3.5, 2.3, 2.9,
  4, 2004, 2, 29, 60, 0.2, 3.7, 0.2, 2,
  4, 2005, 2, 26, 57, 0.8, 4.3, 0.6, 2.1,
  4, 2005, 2, 27, 58, 0, 0.5, -0.5, -0.2,
  4, 2005, 2, 28, 59, 0, 0.2, -4.7, -2.1
)

方案1:生成重叠的连续两年区间分组ID(如2002-2003、2003-2004)

如果需要每个年份的数据同时属于当前年与下一年的区间、以及当前年与上一年的区间(存在的话),可以先构造所有连续年份区间,再通过连接匹配到每个数据行:

library(dplyr)

# 第一步:生成所有连续年份区间及对应的分组ID
year_intervals <- df %>%
  distinct(year) %>%
  arrange(year) %>%
  # 获取每个年份的下一个连续年份
  mutate(next_year = lead(year)) %>%
  # 过滤掉没有下一年的最后一个年份
  filter(!is.na(next_year)) %>%
  # 创建区间名称和分组ID
  mutate(
    year_interval = paste(year, next_year, sep = "-"),
    group_id = row_number()
  )

# 第二步:将原数据与区间连接,匹配每个数据行所属的区间
df_grouped <- df %>%
  left_join(
    year_intervals,
    # 匹配条件:数据行的年份属于区间的起始年或结束年
    by = join_by(year >= year, year <= next_year)
  ) %>%
  # 整理列名
  rename(data_year = year.x) %>%
  select(cell, data_year, year_interval, group_id, everything(), -year.y, -next_year)

运行后,2003年的数据会同时出现在2002-2003(group_id=1)和2003-2004(group_id=2)两个分组中,符合“连续年份区间”的需求。

方案2:用rleid生成非重叠的连续年份分组ID

如果你的需求是将连续的年份划分为非重叠的块(比如2002-2003为一组,2004-2005为另一组),可以结合rleid和年份分组逻辑实现:

library(dplyr)
library(data.table)

df_grouped <- df %>%
  group_by(cell) %>%
  mutate(
    # 计算每个年份所属的非重叠两年块的起始年
    block_start = min(year) + 2 * floor((year - min(year)) / 2),
    # 用rleid对块起始年生成分组ID
    group_id = rleid(block_start),
    # 生成区间名称
    year_interval = paste(block_start, block_start + 1, sep = "-")
  ) %>%
  ungroup()

这里rleid会为每个唯一的block_start生成连续的ID,实现非重叠年份块的分组。

方案3:纯dplyr实现(不依赖data.table)

如果不想使用data.table的rleid,可以用dplyr::dense_rank替代:

library(dplyr)

df_grouped <- df %>%
  group_by(cell) %>%
  mutate(
    block_start = min(year) + 2 * floor((year - min(year)) / 2),
    year_interval = paste(block_start, block_start + 1, sep = "-"),
    group_id = dense_rank(block_start)
  ) %>%
  ungroup()

这个方案和方案2效果一致,只是用dense_rank替代了rleid。

内容的提问来源于stack exchange,提问作者Renan le roux

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 03:15:01