(Concisely/efficiently) 在消除(多个)名称中的首字母时忽略单独的字符

(Concisely/efficiently) ignoring lone characters when eliminating initials in (multiple) names

我正在尝试从大约 1000 万个名字中删除首字母,但我正在寻找一种 efficient/concise 方法来为由单个字符组成的名字构建例外。

例如:

dt<-data.table(fnm=c("audrey e","joe buck","m","w c"),
               lnm=c("claire","b","nop","fields"))

如果我这样做:

nm<-c("fnm","lnm")
dt[,paste0("str_",nm):=lapply(.SD,function(x)gsub("\s|\b[a-z]\b","",x)),
   .SDcols=nm]; rm(nm)

"m""b""w c" 被删除,这给我以后带来了麻烦:

        fnm    lnm str_fnm str_lnm
1: audrey e claire  audrey  claire
2: joe buck      b joebuck        
3:        m    nop             nop
4:      w c fields          fields

一个冗长的替代方案是展开必要的代码行:

dt[gsub("\s","",str_fnm)=="",str_fnm:=fnm]
dt[gsub("\s","",str_lnm)=="",str_lnm:=lnm]

除了冗长之外,这似乎有点低效,因为我还需要进行矢量比较。

基本上,我需要的是一种将单字符异常构建到正则表达式本身的方法;有没有我没有想到的方法?

也许我遗漏了一些细节,但为什么不简单:

sub("( [a-z])+$|^([a-z] )+", "", x)

问题似乎更复杂,可能不值得尝试使用正则表达式来解决。因此,请事后修复它:

for (x in nm) dt[get(paste0('str_', x)) == "", paste0('str_', x) := get(x)]