如何借助索引文件循环比对两CSV列生成QC校验列?
批量实现编码数据集QC校验的tidyverse方案
前提假设
假设你的文件结构如下:
index.csv:包含三列field_name(对应original/processed的列名)、original_text(原始文本值)、processed_code(对应的编码值)original.csv:列名为各个字段,值为原始文本processed.csv:列名与original完全对应,值为编码后的数据
解决方案代码
1. 加载包与读取数据
library(tidyverse) # 读取三个文件 index_df <- read_csv("index.csv") original_df <- read_csv("original.csv") processed_df <- read_csv("processed.csv") # 校验列名一致性(可选,提前排查错误) stopifnot(all(colnames(original_df) == colnames(processed_df))) stopifnot(all(colnames(original_df) %in% index_df$field_name))
2. 构建字段映射表
把index中的映射关系转成按字段分组的命名向量,方便快速匹配:
field_maps <- index_df %>% group_split(field_name) %>% set_names(map(., ~ .$field_name[[1]])) %>% map(~ deframe(select(., original_text, processed_code)))
3. 批量生成QC校验列
合并原始数据与编码数据,用across批量处理每个字段,生成对应的QC列:
# 合并原始数据和编码数据,给编码列加后缀区分 combined_data <- bind_cols( original_df, processed_df %>% rename_with(~ paste0(., "_processed")) ) # 批量生成QC列 final_qc_result <- combined_data %>% mutate( across( all_of(names(field_maps)), ~ case_when( # 任意一方为NA则标记No data is.na(.) | is.na(!!sym(paste0(cur_column(), "_processed"))) ~ "No data", # 编码值与映射表匹配则标记Match !!sym(paste0(cur_column(), "_processed")) == field_maps[[cur_column()]][as.character(.)] ~ "Match", # 其余情况标记Mismatch! TRUE ~ "Mismatch!" ), # 给QC列命名为「原字段名_QC」 .names = "{col}_QC" ) )
4. 输出结果
# 导出到CSV write_csv(final_qc_result, "qc_checked_result.csv")
关键逻辑说明
field_maps:将每个字段的文本-编码映射转成独立的命名向量,避免重复查询整表across+cur_column():动态遍历所有字段,自动匹配对应的编码列,实现批量处理case_when:严格按照需求的规则生成校验结果,优先处理NA情况,再判断匹配性
内容的提问来源于stack exchange,提问作者Ginko-Mitten
相关产品推荐
相关产品推荐

