如何使用R代码检测数据集中各ID的多值异常观测
R代码识别固定属性取值不一致的受访者ID
问题背景
纵向追踪数据集中,同一id对应同一受访者在不同研究阶段phase的重复观测,性别等不随研究阶段变化的固定属性,在同一id下的所有观测中取值应当完全一致。示例数据结构如下:
id gender phase a1 m 1 a1 m 2 a1 m 3 b2 m 1 b2 f 2 b2 m 3 c3 f 1 c3 f 2 c3 f 3 ...
其中其中id==b2、phase==2的观测性别被误标为f,和同id下其他观测的m矛盾,需要批量识别所有存在这类问题的ID。
实现方案
1. 无依赖base R实现
不需要安装任何第三方包,核心逻辑是按id分组,统计每个分组下待校验固定属性的去重取值数量,去重后数量大于1即说明存在取值不一致问题。
# 先构造示例测试数据 df <- data.frame( id = c("a1","a1","a1","b2","b2","b2","c3","c3","c3"), gender = c("m","m","m","m","f","m","f","f","f"), phase = c(1,2,3,1,2,3,1,2,3) ) # 识别存在gender取值不一致的id inconsistent_ids <- names(which( tapply(df$gender, df$id, function(x) length(unique(x)) > 1) )) # 打印结果,示例数据下会输出 "b2" print(inconsistent_ids) # 如果需要查看这些异常id对应的所有原始观测,运行下面代码 inconsistent_records <- df[df$id %in% inconsistent_ids, ]
2. dplyr实现(适合日常使用tidyverse生态的场景)
library(dplyr) inconsistent_ids <- df %>% group_by(id) %>% summarise(unique_gender_cnt = n_distinct(gender)) %>% filter(unique_gender_cnt > 1) %>% pull(id)
扩展用法
- 如果需要同时校验多个固定属性(比如性别、出生年份、籍贯等不随追踪阶段变化的字段),只要把多个字段拼接为组合值再做去重统计即可,以同时校验
gender和birth_year为例:
# base R 多字段校验 inconsistent_ids_multi <- names(which( tapply(interaction(df$gender, df$birth_year), df$id, function(x) length(unique(x)) > 1) ))
- 识别出异常ID后,可以直接按组修正取值,一般取同ID下出现频次最高的取值作为正确值填充即可:
# dplyr 修正示例:将同id下的gender统一为组内出现次数最多的值 df_fixed <- df %>% group_by(id) %>% mutate(gender = names(which.max(table(gender)))) %>% ungroup()
内容的提问来源于stack exchange,提问作者Rstudyer
相关产品推荐
相关产品推荐

