You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言:去除数据框姓名列重复项(含全名与姓氏去重)

问题描述

我有一个包含姓名字符串的数据框:

df = data.frame("names" = c("George Orwell; Ayn Rand; Adam Smith", "George Orwell; Rand; Orwell"))
df
#                                names
# 1 George Orwell; Ayn Rand; Adam Smith
# 2         George Orwell; Rand; Orwell

我需要移除所有重复姓名,规则如下:

  • 仅保留列表中的唯一姓名
  • 当字符串中存在某姓氏对应的全名时,移除单独的姓氏;若没有对应全名,则保留该姓氏

期望得到的结果:

names
1 George Orwell; Ayn Rand; Adam Smith
2                 George Orwell; Rand

目前我用以下代码只能处理完全重复的情况,无法解决姓氏与全名的冗余问题:

sapply(strsplit(df$names, ";\\s*"), function(z) paste(unique(z), collapse = "; "))
# [1] "George Orwell; Ayn Rand; Adam Smith" "George Orwell; Rand; Orwell"   

解决方案

可以通过自定义函数实现姓氏与全名的匹配过滤,具体代码如下:

clean_names <- function(name_vec) {
  # 拆分每个姓名为若干部分,区分全名(多部分)和单姓氏
  split_parts <- strsplit(name_vec, "\\s+")
  # 提取每个姓名的姓氏
  last_names <- sapply(split_parts, function(x) x[length(x)])
  # 筛选出所有全名(包含至少两个部分的姓名)
  full_name_list <- name_vec[sapply(split_parts, length) >= 2]
  # 提取全名对应的姓氏集合
  full_last_names <- sapply(strsplit(full_name_list, "\\s+"), function(x) x[length(x)])
  
  # 过滤规则:单姓氏且对应全名存在则移除,其余保留
  keep_flag <- !((sapply(split_parts, length) == 1) & (last_names %in% full_last_names))
  # 最后做一次完全去重,再合并为字符串
  unique(name_vec[keep_flag])
}

# 将函数应用到数据框的names列
df$cleaned_names <- sapply(strsplit(df$names, ";\\s*"), function(z) {
  paste(clean_names(z), collapse = "; ")
})

# 查看处理后的结果
df$cleaned_names
# [1] "George Orwell; Ayn Rand; Adam Smith" "George Orwell; Rand"

代码说明

  1. 拆分姓名:通过空格拆分每个姓名,判断是全名(多段)还是单姓氏
  2. 提取姓氏:从每个姓名中提取最后一段作为姓氏
  3. 匹配过滤:如果某个单姓氏对应的全名已经存在,则移除该单姓氏
  4. 去重合并:对过滤后的结果做完全去重,再合并为目标格式的字符串

内容的提问来源于stack exchange,提问作者user17661126

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 13:25:50