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

R语言dplyr多变量分组时为数据框生成组内编号的实现方法

问题背景

目前已有多个同类型的R数据框分组编号问题解答,但均未涉及多分组变量下的嵌套编号场景,现有方案无法适配需求。

测试数据

运行以下代码可构造测试用数据集:

library(dplyr)
df <- tibble(
    s1 = c("111", "111", "111", "112", "112", "114", "114", "115"),
    s2 = c(rep("A", 5), rep("B", 3)),
    val = rnorm(8)
)

需求描述

需要在s2的分组范围内为s1分配分组ID,ID规则为:相同s2下,同一个s1的ID值一致,s1取值变化时ID递增,s2取值变化时ID重置为1重新计数,期望输出结构如下:

# A tibble: 8 x 4
  s1    s2        val    id
  <chr> <chr>   <dbl> <dbl>
1 111   A     -0.465      1
2 111   A      0.871      1
3 111   A      0.821      1
4 112   A      0.562      2
5 112   A      0.197      2
6 114   B     -0.743      1
7 114   B      0.0847     1
8 115   B     -1.05       2

已验证无效的方案

以下写法均无法实现上述编号逻辑:

# 仅按s1分组编号,s2切换时不会重置计数
df %>% group_by(s1) %>% mutate(id = row_number())

# 按s1+s2联合分组生成行号,同组内相同s1的行号会逐行递增,无法拿到统一ID
df %>% group_by(s1, s2) %>% mutate(id = row_number())

# 仅按s2分组生成行号,不会识别s1的取值变化
df %>% group_by(s2) %>% mutate(id = row_number())

# 其余错误写法
df %>% group_by(s1) %>% mutate(id = row_number(s2))
df %>% group_by(s1) %>% mutate(id = cur_group_id())
df %>% group_by(s1, s2) %>% mutate(id = cur_group_id())
实现方案

核心逻辑是先按s2拆分数据分组,再在每个s2分组内,按s1的出现顺序生成连续的分组ID,两种常用实现写法如下:

写法1:通用匹配写法(兼容各dplyr版本)

df %>% 
  group_by(s2) %>% 
  mutate(id = match(s1, unique(s1))) %>%
  ungroup()

逻辑说明:

  • group_by(s2)保证所有计算仅在单个s2分组内执行,s2取值变化时计算自动重置
  • unique(s1)按出现顺序提取当前s2分组内所有不重复的s1值
  • match()返回每一行s1在不重复s1列表中的位置,刚好符合编号规则:同个s1拿到相同ID,s1变化ID递增,s2切换ID从1重启

写法2:专用连续ID函数(dplyr 1.0.0及以上版本可用)

df %>% 
  group_by(s2) %>% 
  mutate(id = consecutive_id(s1)) %>%
  ungroup()

consecutive_id()会按列值的连续变化生成递增ID,配合s2分组使用时,刚好实现组内按s1变化生成编号的需求,写法更简洁。

两种写法运行结果和期望输出完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 20:18:13