使用R语言stringr包标准化作者姓名格式的技术求助
统一作者姓名格式的解决方案
需求说明
现有一组格式不一致的作者姓名数据,需要提取每个姓名的首字母缩写(initials)、姓氏前缀(全小写单词,若存在)、**姓氏(首字母大写的单词)**三类组件,重新组合为「首字母缩写(字母间加句点)+ 姓氏前缀(若有)+ 姓氏」的标准格式,最终按Id分组,多作者列表根据数量用逗号分隔前几位,最后一位用&连接。
数据集样本:
library(tidyverse) sample_list <- structure(list(Id = c(22667, 33807, 3625, 35531, 32051, 27721), auteur = c("van Bar, A.J.M.", "de Vogel, J.J., R. Robbing, M.J. Smit & H.L.T. Bergsma-John", "Stark, M. ten", "Eeden, F.W. van", "Bouman, F. & F.D. Parker", "Sullock Enzlin, R.A.F. & J. Hoenselaar"), jaartal = c(1938, 2016, 2002, 1889, 1997, 1991)), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))
已完成组件提取的基础代码,但需要补充重组和分组逻辑,预期输出示例:
- "A.J.M. van Bar"
- "J.J. de Vogel, R. Robbing, M.J. Smit & H.L.T. Bergsma John"
- "M. ten Stark"
- "F.W. van Eeden"
- "F. Bouman & F.D. Parker"
- "R.A.F. Sullock Enzlin & J. Hoenselaar"
完整解决方案代码
library(tidyverse) sample_list |> # 清理多余逗号并拆分单个作者条目 mutate(auteur = str_remove(auteur, pattern = ",")) |> separate_longer_delim(cols = auteur, delim = regex("\\, | &")) |> mutate(auteur = str_squish(auteur)) |> # 提取并格式化三类组件 mutate( # 提取首字母并重新格式化为带句点的标准样式 initials = auteur |> str_extract(pattern = "(\\b[A-Z\\.]+\\b)") |> str_remove_all(pattern = "\\.") |> str_split("") |> map_chr(~paste(.x, collapse = ".")) |> str_c(".", sep = ""), # 提取姓氏,将复合姓氏的连字符替换为空格 last_name = auteur |> str_extract_all(pattern = "\\b\\p{Lu}(?:\\p{Lu}*\\p{lu})?\\w+") |> map_chr(paste, collapse = " ") |> str_replace_all("-", " "), # 提取全小写的姓氏前缀 prefix = auteur |> str_extract(pattern = "\\b[a-z](?:[a-z ]*[a-z])?\\b") |> str_squish() ) |> # 重组单个作者的标准姓名 mutate(standard_name = case_when( !is.na(prefix) & prefix != "" ~ str_c(initials, " ", prefix, " ", last_name), TRUE ~ str_c(initials, " ", last_name) )) |> # 按Id分组,拼接多作者列表 group_by(Id, jaartal) |> summarise( formatted_authors = case_when( n() == 1 ~ standard_name, n() == 2 ~ str_c(standard_name, collapse = " & "), n() > 2 ~ str_c(c(str_c(standard_name[1:(n()-1)], collapse = ", "), standard_name[n()]), collapse = " & ") ), .groups = "drop" )
关键步骤说明
- 拆分作者条目:先用
str_remove清理字符串中多余的逗号,再通过separate_longer_delim按,或&拆分出每个独立的作者条目。 - 组件处理:
- 首字母缩写:提取大写字母片段后,拆分为单个字母并重新用句点连接,确保统一为
A.J.M.的格式。 - 姓氏:提取首字母大写的单词,将复合姓氏中的连字符替换为空格(如
Bergsma-John转为Bergsma John)。 - 姓氏前缀:精准匹配提取全小写的前缀单词(如
van、ten)。
- 首字母缩写:提取大写字母片段后,拆分为单个字母并重新用句点连接,确保统一为
- 重组单个姓名:通过
case_when判断是否存在前缀,拼接成符合要求的标准姓名格式。 - 分组拼接多作者列表:根据每组的作者数量,分别处理1个、2个、多个作者的拼接逻辑,保证前几位用逗号分隔,最后一位用
&连接,符合学术写作的格式规范。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

