如何在R语言数据框中按组递增数值型id并保留组间间隔?
在R语言中实现组内ID连续且组间保留1个间隔的方法
给定第一列为分组变量、第二列为递增ID的数据框,我们需要实现组内ID连续,组与组之间ID保留1个间隔的效果。比如以下输入数据:
df <- data.frame(group=c(rep('a',3),rep('b',3), rep('c', 3)), id=c(1,2,3,4,5,6,7,8,9))
想要得到的结果是组内ID连续,组间间隔1个数值,最终数据框如下:
group id 1 a 1 2 a 2 3 a 3 4 b 5 5 b 6 6 b 7 7 c 9 8 c 10 9 c 11
下面提供两种常用实现方法:
方法一:使用dplyr包(tidyverse生态)
适合习惯tidyverse语法的用户,代码逻辑清晰:
library(dplyr) df_new <- df %>% # 按分组统计每组的行数 group_by(group) %>% mutate(group_size = n()) %>% ungroup() %>% # 计算每个组的起始偏移:前面所有组的总长度 + 前面组的数量(每个组间隔1) mutate(start_offset = cumsum(lag(group_size, default = 0)) + (group != lag(group, default = first(group))) %>% cumsum() - 1) %>% # 分组生成新ID:组内行号 + 该组的起始偏移 group_by(group) %>% mutate(id = row_number() + start_offset[1]) %>% select(group, id) %>% ungroup() print(df_new)
方法二:使用基础R实现
无需加载额外包,适合轻量需求:
# 统计每个分组的行数 group_sizes <- tapply(df$id, df$group, length) # 计算每个分组的起始ID:第一个组从1开始,后续组起始=前面所有组总长度+前面组的数量(间隔数) start_ids <- c(1, cumsum(group_sizes[-length(group_sizes)]) + seq_along(group_sizes[-length(group_sizes)])) # 为每个分组生成连续ID并替换原id列 df$id <- unlist(mapply(function(start, len) start:(start + len - 1), start_ids, group_sizes)) print(df)
两种方法都能得到目标结果,可根据自己的代码习惯选择。
内容的提问来源于stack exchange,提问作者zhang
相关产品推荐
相关产品推荐

