如何使用R Validate包定位每行数据违反的校验规则?
问题:如何在R的Validate包中关联违规行与对应的规则?
我正在用R的Validate包处理野外录入数据及历史杂乱数据的QC工作,已经掌握validator()编写规则、confront()统计违规次数、violating()查看违规行的基础操作,但需要明确哪些规则在哪些行被违反——实际数据集包含50+变量及更多规则,单一行可能违反多条规则。
现有示例代码:
# 示例数据集 plot <- 1:4 DBH <- c(1.1, 2, 0.7, 3.2) df <- data.frame(plot, DBH) # 编写规则:DBH必须≥1 rule <- validator(DBH >= 1) # 校验数据集 x <- confront(df, rule) summary(x) # 查看违规行 y <- violating(df, rule) y
需求:将违规行与违反的具体规则关联,比如在输出中添加列标注该行违反的规则(已了解可为规则添加名称和描述,需整合到输出)。
解决方案
核心思路
给每条规则命名,通过confront()的结果转换为结构化数据,再与原数据集合并,最终提取每行对应的违规规则。以下提供两种常用方法:
方法1:生成宽格式结果,每行展示所有违规规则
适合快速查看单条记录的所有违规项:
# 1. 给规则添加名称(可同时添加描述) rules <- validator( dbh_min = DBH >= 1 ~ "胸径不能小于1cm", dbh_max = DBH <= 3 ~ "胸径不能大于3cm", plot_pos = plot > 0 ~ "样地编号必须为正整数" ) # 2. 执行校验并转换为数据框(每行对应每条规则的通过/违规状态) validation_result <- as.data.frame(confront(df, rules)) # 3. 合并原数据与校验结果,提取违规明细 library(dplyr) violation_detail <- cbind(df, validation_result) %>% rowwise() %>% # 拼接该行所有违规的规则名称 mutate(violated_rules = paste(names(validation_result)[c_across(all_of(names(validation_result))) == FALSE], collapse = ", ")) %>% # 筛选出有违规的行 filter(violated_rules != "") %>% ungroup() # 查看结果 violation_detail
输出示例:
plot DBH dbh_min dbh_max plot_pos violated_rules 1 3 0.7 FALSE TRUE TRUE dbh_min 2 4 3.2 TRUE FALSE TRUE dbh_max
方法2:生成长格式结果,每条违规记录单独一行
适合批量统计、分析所有违规项(尤其一行违反多条规则时):
# 1. 使用命名后的规则 rules <- validator( dbh_min = DBH >= 1, dbh_max = DBH <= 3, plot_pos = plot > 0 ) # 2. 执行校验并转为长格式 validation_long <- as.data.frame(confront(df, rules)) %>% mutate(row_id = row_number()) %>% tidyr::pivot_longer( cols = -row_id, names_to = "rule_name", values_to = "is_compliant" ) %>% filter(!is_compliant) # 3. 合并原数据与违规记录 violation_long <- df %>% mutate(row_id = row_number()) %>% inner_join(validation_long, by = "row_id") %>% select(-row_id, -is_compliant) # 查看结果 violation_long
输出示例:
plot DBH rule_name 1 3 0.7 dbh_min 2 4 3.2 dbh_max
补充说明
- 若需要展示规则描述,可通过
rule_descriptions(rules)获取规则名称与描述的对应表,再合并到结果中; - 对于大型数据集,两种方法均能高效处理,长格式更便于后续的违规规则统计或可视化。
内容的提问来源于stack exchange,提问作者Emily
相关产品推荐
相关产品推荐

