如何标准化数据框中存储高校名称的非数值列的不规范内容?
问题原因
你之前的代码会产生重复是因为:对每一行的机构名称,你调用str_detect(.x,DB_CO$affiliation)会返回所有符合匹配规则的全表机构名称条目,单个原始值匹配到多个结果时,unnest操作就会把一行拆成多行,导致单条记录重复。
解决方案
方案1:手动映射规则(准确率最高,优先推荐)
提前定义好标准名称和匹配关键词的映射规则,每一条原始机构名只会返回唯一的标准结果,不会产生重复:
library(tidyverse) # 1. 定义机构映射规则:键为最终标准名称,值为匹配用的正则关键词,不区分大小写 org_mapping <- list( "OXFORD UNIVERSITY" = "oxford|oford", "UNIVERSIDAD NACIONAL DE BOGOTÁ" = "universidad nacional", "UNIVERSIDAD DEL VALLE" = "(unievrsidad|universidad) del valle", "UPTC" = "^uptc$", "PONTIFICIA UNIVERSIDAD JAVERIANA CALI" = "javeriana|pontificia universidad javeriana" ) # 2. 定义匹配函数 match_std_org <- function(raw_name, mapping) { raw_low <- str_to_lower(raw_name) for (std_name in names(mapping)) { if (str_detect(raw_low, mapping[[std_name]])) { return(std_name) } } # 未匹配到的返回原值,方便后续补充规则 return(raw_name) } # 3. 处理数据 DB_CO1 <- DB_CO %>% mutate(所属机构 = map_chr(所属机构, ~match_std_org(.x, org_mapping)))
方案2:模糊匹配(适合机构数量多、不想手动写规则的场景)
基于字符串编辑距离匹配最相近的标准名称,无需手动写大量匹配规则:
library(tidyverse) library(stringdist) # 1. 预先定义所有标准机构名称 std_org_list <- c( "OXFORD UNIVERSITY", "UNIVERSIDAD NACIONAL DE BOGOTÁ", "UNIVERSIDAD DEL VALLE", "UPTC", "PONTIFICIA UNIVERSIDAD JAVERIANA CALI" ) # 2. 匹配最近的标准名称 DB_CO1 <- DB_CO %>% mutate(所属机构 = map_chr(所属机构, ~{ # 计算和所有标准名的编辑距离,取最小的对应标准名 dist_vec <- stringdist(str_to_lower(.x), str_to_lower(std_org_list), method = "lv") std_org_list[which.min(dist_vec)] }))
注意事项
- 手动映射方案适配性最强,出现新的异构名称时仅需补充
org_mapping里的规则即可 - 模糊匹配方案使用前建议先抽样校验匹配结果,避免距离判定错误导致的归一化异常
内容的提问来源于stack exchange,提问作者Andrés Felipe Tigreros-Andrade
相关产品推荐
相关产品推荐

