R语言如何基于外部参考表校验数据值的合法性
基于参考值表批量识别数据集异常值的R实现
需求说明
- 已有存储各列合法取值的参考表
good_df,需要依托该表找出待校验数据集test_df中不符合合法取值范围的异常值 - 实际场景下合法列值映射对、待校验列数远多于示例,优先支持管道操作、减少临时变量的简洁写法,也可接受其他合法值存储形式的实现方案
示例测试数据
library(tidyverse) # 合法取值参考表 good_df <- tribble( ~column, ~value, "col1", "a", "col1", "b", "col1", "c", "col1", "d", "col1", "e", "col2", "A", "col2", "B", "col2", "C" ) # 构造测试待校验数据集,其中col2列的"D"为预设非法值 set.seed(1) test_df <- tibble( col1 = sample(letters[1:3], 4, T), col2 = c(sample(LETTERS[1:3], 3, T), "D"), col3 = rnorm(4) ) test_df #> # A tibble: 4 × 3 #> col1 col2 col3 #> <chr> <chr> <dbl> #> 1 a A 0.330 #> 2 c C -0.820 #> 3 a C 0.487 #> 4 b D 0.738
初期尝试的问题
- 最初思路是调用
pivot_longer将test_df转换为和good_df结构一致的长表,再通过集合差集剔除所有合法行,剩余记录即为异常值,但始终无法正确配置pivot_longer参数实现预期效果 - 尝试使用
validate包实现,但未在文档中找到通过显式枚举允许/禁止值创建校验规则的方法
最终通用实现
通过tidyverse管道操作即可实现无临时变量的简洁校验,代码可直接复用至大规模数据集场景:
test_df %>% pivot_longer(cols = any_of(good_df$column), names_to = "column", values_to = "value") %>% select(column, value) %>% anti_join(good_df)
代码逻辑说明
pivot_longer阶段通过any_of(good_df$column)自动匹配所有需要校验的列,未在参考表中定义规则的列(如示例中的col3)会被自动跳过,无需手动枚举列名- 转换为长表后筛选出和参考表一致的
column、value字段,通过anti_join反连接剔除所有合法的「列名-取值」组合,剩余结果即为所有异常值
上述代码运行后会正确返回
col2列的取值"D"为非法值,和预期结果完全一致。
内容的提问来源于stack exchange,提问作者Rob Creel
相关产品推荐
相关产品推荐

