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

使用R正则表达式拆分多格式姓名至名、中间名、姓氏

拆分带首字母缩写的姓名数据框

问题说明

我有一个包含多种格式姓名的数据框,需要将姓名拆分为名、中间名和姓氏。示例数据框如下:

df1 <- data.frame(name = c("Matt Smith", "Matt L. Smith", "Matt Louis Smith",
                           "M. Smith", "M.L. Smith", "M.L. Smith, Jr.", "M. Smith, Jr.", "Unknown"))

现有代码能正确处理非首字母缩写的姓名,但遇到名和中间名均为缩写的情况(如M.L. Smith)时会失效。现有代码及输出如下:

library(dplyr)
library(tidyr)

names <- df1 %>%
  mutate(name = gsub('([A-Za-z\\.?]+) ([A-Za-z\\.]+ )?([A-Za-z]+)?', '\\1=\\2=\\3', name)) %>%
  separate(name, c("Collector.First.Name1", "Collector.Middle1", "Collector.Last.Name1"), "=")

print(names)

输出结果:

Collector.First.Name1 Collector.Middle1 Collector.Last.Name1
1                  Matt                                  Smith
2                  Matt               L.                 Smith
3                  Matt            Louis                 Smith
4                    M.                                  Smith
5                  M.L.                                  Smith
6                  M.L.                             Smith, Jr.
7                    M.                             Smith, Jr.
8               Unknown                                     

期望输出

需要正确拆分首字母缩写的情况,理想输出如下:

Collector.First.Name1 Collector.Middle1 Collector.Last.Name1
1                  Matt                                  Smith
2                  Matt               L.                 Smith
3                  Matt            Louis                 Smith
4                    M.                                  Smith
5                    M.               L.                 Smith
6                    M.               L.            Smith, Jr.
7                    M.                             Smith, Jr.
8               Unknown                                     

解决方案

使用dplyr和stringr工具,先处理连续首字母缩写的格式,再拆分姓名各部分:

library(dplyr)
library(stringr)

df1 <- data.frame(name = c("Matt Smith", "Matt L. Smith", "Matt Louis Smith",
                           "M. Smith", "M.L. Smith", "M.L. Smith, Jr.", "M. Smith, Jr.", "Unknown"))

df_result <- df1 %>%
  # 将连续首字母缩写(如M.L.)替换为空格分隔的独立缩写
  mutate(name = str_replace_all(name, "([A-Z])\\.([A-Z])\\.", "\\1. \\2.")) %>%
  # 按空格拆分姓名为多个部分
  mutate(name_parts = str_split(name, "\\s+")) %>%
  # 提取姓氏:取最后一个部分
  mutate(Collector.Last.Name1 = sapply(name_parts, function(x) tail(x, 1))) %>%
  # 提取名和中间名:取除最后一个外的部分
  mutate(first_middle_parts = sapply(name_parts, function(x) head(x, -1))) %>%
  # 提取名:取first_middle_parts的第一个元素
  mutate(Collector.First.Name1 = sapply(first_middle_parts, function(x) if(length(x) >= 1) x[1] else NA)) %>%
  # 提取中间名:取first_middle_parts的第二个元素,没有则为空
  mutate(Collector.Middle1 = sapply(first_middle_parts, function(x) if(length(x) >= 2) x[2] else "")) %>%
  # 处理"Unknown"的特殊情况
  mutate(
    Collector.First.Name1 = ifelse(name == "Unknown", "Unknown", Collector.First.Name1),
    Collector.Last.Name1 = ifelse(name == "Unknown", "", Collector.Last.Name1)
  ) %>%
  # 移除中间辅助列
  select(-name_parts, -first_middle_parts)

print(df_result)

运行后即可得到符合预期的拆分结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:05:35