R语言dplyr:分组内间隔重复项的重复次数统计问题
问题描述
我有一个分组数据集,同一组内的ID可能在多个位置重复出现。我需要统计每个组内各ID的总重复次数,后续用于筛选操作。以下是示例数据集:
structure(list(Group = c(1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3), ID = c("non repeating", "repeating", "repeating", "repeating", "repeating", "non repeating", "repeating", "repeating", "non repeating", "repeating", "repeating", "repeating", "non repeating")), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -13L))
我期望得到每个组内重复ID对应其重复次数、非重复ID次数为0的输出。我尝试了以下代码:
ex <- ex_data %>% group_by(Group) %>% mutate( Value = case_when( ID == lag(ID) ~ 1, TRUE ~ 0 ) ) %>% mutate( Value = case_when( ID == lead(ID) ~ 1, TRUE ~ Value ) ) %>% group_by(ID, .add = T) %>% mutate(count = sum(Value))
但结果不符合预期,数值是跨组求和而非按组和ID分别求和,请问我哪里出错了?
问题分析与解决方法
你的代码问题出在两次分组叠加后,求和逻辑没有精准限定在「组+ID」的组合内,而且用lag和lead标记重复的方式本身存在冗余——连续重复的ID会被多次标记,导致统计结果偏差。
更简洁准确的做法是直接按Group和ID组合分组,先统计每个ID在组内的出现次数,再推导重复次数:
- 重复次数 = 出现次数 - 1(出现次数>1时),非重复ID直接设为0
具体代码如下:
ex <- ex_data %>% group_by(Group, ID) %>% mutate( # 统计组内当前ID的总出现次数 total = n(), # 计算重复次数:非重复ID次数为0,重复ID为出现次数减1 count = ifelse(total > 1, total - 1, 0) ) %>% ungroup() # 按需取消分组
如果要保留你原本的标记思路修复问题,需要调整分组顺序,确保求和范围严格限定在「组+ID」内:
ex <- ex_data %>% group_by(Group, ID) %>% mutate( # 同一组同ID内,标记当前行是否与前后行重复 Value = case_when( ID == lag(ID) | ID == lead(ID) ~ 1, TRUE ~ 0 ), # 在组+ID的分组内求和,同时忽略lead/lag产生的NA值 count = sum(Value, na.rm = TRUE) ) %>% ungroup()
不过这种方法代码更繁琐,效率也不如直接统计出现次数的方案。
内容的提问来源于stack exchange,提问作者r_user
相关产品推荐
相关产品推荐

