使用R识别同一PersonID分组内属性差异并导出数据
提取DataFrame中同一PersonID组内存在属性差异的记录
需求:现有一个包含人员属性的DataFrame,以PersonID作为唯一标识,部分PersonID对应多条记录。需要筛选出所有同一PersonID分组内,Sex、DOB、Race任意属性存在差异的记录,输出到单独的DataFrame中。
示例数据
PersonID Sex DOB Race 10123 M 10/12/1986 A 10123 M 10/12/1986 A 25694 M 08/21/1957 W 25694 F 08/21/1957 W 45899 F 04/12/1975 W 45899 F 04/12/1975 U 10229 M 05/17/1989 W 10229 M 05/17/1989 W 10229 M 05/17/1989 W 69897 F 09/10/1995 U 69897 F 09/10/1995 U 69897 F 09/20/1995 A 55554 M 04/02/1988 B 55554 M 04/02/1988 B
期望输出
25694 M 08/21/1957 W 25694 F 08/21/1957 W 45899 F 04/12/1975 W 45899 F 04/12/1975 U 69897 F 09/10/1995 U 69897 F 09/10/1995 U 69897 F 09/20/1995 A
已尝试代码
library(dplyr) test <- myData %>% add_count(PersonId) %>% filter(n > 1) %>% select(PersonId, Sex, DOB, Race)
解决方案
基于dplyr实现组内差异检测,核心思路是按PersonID分组后,检查目标属性的唯一值数量是否大于1,只要任意一个属性满足该条件,就保留该组的所有记录:
library(dplyr) # 提取存在属性差异的组的所有记录 diff_records <- myData %>% group_by(PersonID) %>% mutate( # 标记每个属性是否存在差异 sex_has_diff = n_distinct(Sex) > 1, dob_has_diff = n_distinct(DOB) > 1, race_has_diff = n_distinct(Race) > 1, # 标记该组是否存在任意属性差异 has_any_diff = sex_has_diff | dob_has_diff | race_has_diff ) %>% # 筛选出存在差异的组的记录 filter(has_any_diff) %>% # 移除中间标记列 select(-sex_has_diff, -dob_has_diff, -race_has_diff, -has_any_diff) %>% ungroup()
代码说明
group_by(PersonID):按人员唯一标识分组n_distinct(col) > 1:统计属性的唯一值数量,大于1表示该属性在组内存在差异has_any_diff:只要任意一个属性存在差异,该标记为TRUEfilter(has_any_diff):保留所有存在差异的组的记录select(-...):移除中间生成的标记列,得到干净的结果
内容的提问来源于stack exchange,提问作者Timothy Kellogg
相关产品推荐
相关产品推荐

