如何在base R或dplyr中按条件生成元素分组的reSeq序列列?
解决方案:按规则生成reSeq列
需求说明
对数据框按Element分组后生成reSeq列,规则如下:
Group=0(未分组)的每个单独实例按顺序递增序号Group>0的同一分组内所有行共享同一个序号,且序号按分组出现的顺序依次分配,与未分组的序号连续递增
dplyr 实现方案
library(dplyr) # 原始数据框 myDF <- data.frame( Element = c("R","R","X","X","X","X","X","X","B","R","R","R","X","X","X"), Group = c(0,0,0,1,1,0,0,0,0,0,2,2,3,3,3) ) # 生成目标reSeq列 result_df <- myDF %>% group_by(Element) %>% mutate( # 为每个行生成唯一标识:未分组用组内行号,非分组用Element+Group的组合 group_id = ifelse(Group == 0, row_number(), paste0(Element, "_", Group)), # 为每个唯一标识分配连续递增的序号 reSeq = match(group_id, unique(group_id)) ) %>% select(-group_id) # 移除临时辅助列 # 查看结果 print(result_df)
代码说明
- 按
Element分组,确保每个元素的序号独立计算 - 生成
group_id:未分组的行用组内行号作为唯一标识(保证每个未分组实例序号唯一递增),非分组的行用Element_Group组合作为统一标识(保证同一分组的行序号相同) - 通过
match()函数,将每个group_id映射到其在唯一序列中的位置,得到连续递增的reSeq
Base R 实现方案
# 原始数据框 myDF <- data.frame( Element = c("R","R","X","X","X","X","X","X","B","R","R","R","X","X","X"), Group = c(0,0,0,1,1,0,0,0,0,0,2,2,3,3,3) ) # 按Element拆分数据框并逐组处理 myDF$reSeq <- unlist(lapply(split(myDF, myDF$Element), function(sub_df) { # 生成组内标识:未分组用行号,非分组用Group值 group_tag <- ifelse(sub_df$Group == 0, seq_len(nrow(sub_df)), sub_df$Group) # 分配连续序号 match(group_tag, unique(group_tag)) })) # 查看结果 print(myDF)
代码说明
- 用
split()按Element拆分数据框,对每个子数据框单独处理 - 生成
group_tag:未分组的行用子数据框内的行号,非分组的行直接用Group值 - 同样通过
match()映射序号,最后用unlist()将各组结果合并到原数据框的reSeq列
内容的提问来源于stack exchange,提问作者Village.Idyot
相关产品推荐
相关产品推荐

