Поскольку ваши данные не в фиксированном столбцовом порядке, я думаю, что слишком много условных логик c, чтобы попытаться собрать все это в поддерживаемом регулярном выражении в R. Я даже не уверен, как вы могли бы сказать, какие имена являются первыми именами, а какие вторыми, если инициалы не используются, поскольку порядок не является согласованным.
Однако, основываясь на правилах, подразумеваемых тем, как вы анализировали имена вручную, вот некоторый код, который можно копировать эти правила:
extract_initials <- function(x)
{
y <- lapply(strsplit(x, " "), function(z) z[nzchar(z)])
sapply(y, function(z){
if(length(z) == 1) return("")
else if(!all(grepl("[a-z]", z)))
return(paste(grep("[a-z]", z, invert = T, value = T), collapse = " "))
else return(paste(z[length(z)], collapse = " "))
})
}
extract_first <- function(x)
{
y <- lapply(strsplit(x, " "), function(z) z[nzchar(z)])
sapply(y, function(z){
if(length(z) == 1) return(z)
else if(!all(grepl("[a-z]", z)))
return(paste(grep("[a-z]", z, value = T), collapse = " "))
else return(paste(z[-length(z)], collapse = " "))
})
}
split_name <- function(x)
{
partlist <- strsplit(x, ",(?=[^,]*$)", perl = TRUE)
surnames <- sapply(partlist, `[`, 1)
forenames <- sapply(partlist, `[`, 2)
data.frame(surname = surnames,
first = extract_first(forenames),
middle = extract_initials(forenames),
stringsAsFactors = FALSE)
}
, и он работает так же просто, как это:
split_name(df$FULLNAME)
#> surname first middle
#> 1 John Smith J.
#> 2 David Cameron
#> 3 Adam-Steve Johnson M.
#> 4 Antonio Zang-Chi K
#> 5 Joan Philippe Luis Carlos
#> 6 Dave, Jr. Danny Rock
#> 7 Jake Joan-Anberto
#> 8 Annie Selena L.K
#> 9 Anna Zhei P.
Создано в 2020-03-20 пакетом prex ( v0.3.0)