R语言如何按条件分组生成规则递增的New_Record_ID
需求说明
基于数据集中的Stores、Current_Record_ID两列生成新列New_Record_ID,规则如下:
- 基础规则:同一
Current_Record_ID分组下,每2个Stores共用同一个New_Record_ID,超出2个门店时New_Record_ID依次+1递增,所有分组按顺序顺延赋值,不重置计数 - 拓展规则:支持自定义单个
New_Record_ID关联的最大门店数(如拓展需求要求上限为100),适配包含n个门店的大规模数据集
测试数据集
第一组测试数据集
df <- data.frame( Stores = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), Current_Record_ID = c(1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4) )
第二组测试数据集
df <- data.frame( Stores = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20), Current_Record_ID = c(1, 1, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 6, 7, 7, 7, 8) )
实现方案
核心采用向量化计算逻辑,无嵌套循环,性能足以支撑千万行级大规模数据集,支持自定义单ID关联的门店上限。
首先加载dplyr包,封装通用生成函数:
library(dplyr) gen_new_record_id <- function(df, max_per_id = 2) { df %>% # 按Current_Record_ID分组,为组内门店生成顺序编号 group_by(Current_Record_ID) %>% mutate( inner_rank = row_number(), # 按max_per_id切分组内分段 seg_id = ceiling(inner_rank / max_per_id) ) %>% ungroup() %>% # 识别分段边界,全局生成连续递增的New_Record_ID mutate( New_Record_ID = cumsum( c(1, as.integer( (Current_Record_ID[-1] != Current_Record_ID[-n()]) | (seg_id[-1] != seg_id[-n()]) )) ) ) %>% # 移除计算过程生成的临时列 select(-inner_rank, -seg_id) }
调用方式
- 满足基础规则(每2个门店共用1个New_Record_ID):直接传入数据集即可
df_result <- gen_new_record_id(df) - 满足拓展需求(单个New_Record_ID关联门店数不超过100):修改
max_per_id参数df_result <- gen_new_record_id(df, max_per_id = 100)
结果验证
- 第一组测试集运行基础规则后,
New_Record_ID列输出为c(1,1,2,2,3,3,4,4,5,5,6,6),完全匹配规则要求 - 第二组测试集运行基础规则后,
New_Record_ID列输出为c(1,1,2,3,3,4,5,5,6,6,7,7,8,9,9,10,11,11,12,13),符合跨组顺延、超2个门店自动ID+1的逻辑 - 大规模数据集场景下,向量化计算的性能远高于逐行循环写法,设置
max_per_id=100即可自动完成ID切分,不会出现单ID关联门店数超阈值的问题
内容的提问来源于stack exchange,提问作者Shank
相关产品推荐
相关产品推荐

