R语言大数据集下Inv_name列与Firma列人名部分匹配次数统计及代码问题求助
解决R语言中人名部分匹配次数统计问题
咱们先梳理下你遇到的问题:原代码出现未初始化列的警告,且tmpName返回NA,导致匹配统计失效。下面一步步修复并优化你的代码:
原代码的核心问题分析
- 未初始化目标列:直接给
df1$count2[i]赋值,但count2列还没在数据框中创建,所以触发警告 - 变量名不一致:你提供的数据集是
df,但代码里用的是df1,这会导致找不到数据 - 人名处理逻辑缺陷:拆分后的头衔(如
Prof. Dr.)处理不彻底,且矩阵格式的拆分结果未正确转为向量,引发NA问题
修复后的代码(循环版本)
首先我们先修正基础问题,再优化人名匹配逻辑:
library(stringr) library(dplyr) # 先复制数据集,避免修改原数据 df_processed <- df # 初始化count2列,避免未初始化警告 df_processed$count2 <- 0 for (i in 1:nrow(df_processed)) { # 提取当前行的Inv_name,转为小写 current_name <- str_to_lower(df_processed$Inv_name[i]) # 拆分人名,提取逗号前的核心姓名部分(比如"Meyer, Helmut-Walter") name_parts <- str_split(current_name, ",", simplify = TRUE)[,1] # 进一步清理:去掉头衔(Dr./Prof.等)和多余空格 cleaned_name <- str_remove_all(name_parts, "\\b(?:prof|dr|sc)\\.?\\s*") %>% str_squish() # 去除多余空格 # 构建正则模式:匹配姓名在Firma中的任意位置(部分匹配) pattern <- str_c("\\b", cleaned_name, "\\b", sep = "") # 统计Firma列中匹配的次数(忽略大小写) match_count <- sum(str_detect(str_to_lower(df_processed$Firma), pattern)) # 赋值到count2列 df_processed$count2[i] <- match_count } # 查看结果 df_processed %>% select(Inv_name, Firma, count2)
更高效的Tidyverse风格实现(推荐)
循环在大数据集上效率较低,我们可以用rowwise()结合map_int来实现更简洁高效的代码:
library(tidyverse) df_processed <- df %>% rowwise() %>% mutate( # 清理人名:提取核心部分,去掉头衔 cleaned_name = str_to_lower(Inv_name) %>% str_split(",") %>% pluck(1, 1) %>% str_remove_all("\\b(?:prof|dr|sc)\\.?\\s*") %>% str_squish(), # 统计匹配次数 count2 = sum(str_detect(str_to_lower(Firma), str_c("\\b", cleaned_name, "\\b"))) ) %>% ungroup() %>% select(Inv_name, cleaned_name, Firma, count2)
关键优化点说明
- 初始化目标列:提前创建
count2列,避免未初始化警告 - 精准提取核心人名:先提取逗号前的姓氏部分,再移除
Prof./Dr.等头衔,减少误匹配 - 使用单词边界
\\b:避免部分字符匹配(比如避免"Meyer"匹配"Meyster") - 统一大小写:全部转为小写后匹配,避免大小写敏感导致的漏匹配
运行上述代码后,就能正确统计每个Inv_name中的人名在Firma列的部分匹配次数啦~
内容的提问来源于stack exchange,提问作者Martina Buratti
相关产品推荐
相关产品推荐

