【问题标题】:Proper capitalization of name strings mixed in with company names与公司名称混合的名称字符串的正确大写
【发布时间】:2015-05-24 03:47:09
【问题描述】:

我有一个所有大写的所有者名称列表,我想将其转换为正确的大写:

                   owner1
 1:    DXXXXX JOSEPH V JR
 2:          MIRNA NXXXXX
 3:          ADRIAN TXXXX
 4: CUTLER PXXXXXXXXX LLC
 5:    GVM PXXXXXXXXX LLC
 6:      EARLENA RXXXXXXX
 7:      NATHANIEL TXXXXX
 8:         DXXXXXX DONNA
 9:     LXXXX ELAINE E TR
10:      SXXXXXX KIMBERLY

(用于复制目的:

 owner1<-c("DXXXXX JOSEPH V JR","MIRNA NXXXXX","ADRIAN TXXXX",
           "CUTLER PXXXXXXXXX LLC","GVM PXXXXXXXXX LLC",
           "EARLENA RXXXXXXX","NATHANIEL TXXXXX","DXXXXXX DONNA",
           "LXXXX ELAINE E TR","SXXXXXX KIMBERLY")

)

期望的输出:

                   owner1
 1:   Dxxxxx Joseph V. Jr
 2:          Mirna Nxxxxx
 3:          Adrian Txxxx
 4: Cutler Pxxxxxxxxx LLC
 5:    GVM Pxxxxxxxxx LLC
 6:      Earlena Rxxxxxxx
 7:      Nathaniel Txxxxx
 8:         Dxxxxxx Donna
 9:    Lxxxx Elaine E. TR
10:      Sxxxxxx Kimberly

重要的第一步是?chartr 中提到的.simpleCap 函数的一个版本:

.simpleCap <- function(x) {
    s <- strsplit(tolower(x), " ")[[1]]
    paste(toupper(substring(s, 1, 1)), substring(s, 2),
          sep = "", collapse = " ")
}

这是问题的很大一部分,但在 4、5 和 9 上都失败了。我可以补充它以分别处理关键短语(LLC、TR 等),但这仍然留下类似于观察 5 的内容。

这是我目前得到的函数(下面的@eipi10 的解决方案大大加快了速度,该解决方案对.simpleCap 函数进行了矢量化,允许将整个函数应用于向量):

to.proper<-function(strings){
  #vectorized version of .simpleCap;
  #  I've also built in that I know `strings` is all caps
  res<-gsub("\\b([A-Z])([A-Z]+)*","\\U\\1\\L\\2",strings,perl=T)
  #In my data, some Irish/Scottish names separated the MC prefix
  #  Also, re-capitalize following a hyphen
  res<-gsub("\\bMc\\s","Mc",gsub("(-.)","\\U\\1",res,perl=T))
  for (init in c("[A-Z]","Inc","Assoc","Co",
                 "Jr","Sr","Tr","Bros")){
    #Add a period after common abbreviations
    res<-gsub(paste0("\\b(",init,")\\b"),"\\1.",res)
  }
  for (abbr in c("[B-DF-HJ-NP-TV-XZ][b-df-hj-np-tv-xz]{2,}",
                 "Pa","Ii","Iii","Iv","Lp","Tj",
                 "Xiv","Ll","Yml","Us")){
    #Re-capitalize any string of >=3 consonants (excluding
    #   Y for such names as LYNN and WYNN), as well as
    #   some other common phrases that need upper-casing
    res<-gsub(paste0("\\b(",abbr,")\\b"),"\\U\\1",res,perl=T)
  }
  #Re-capitalize post-Mc letters, e.g. in Mcmahon
  gsub("\\bMc([a-z])","Mc\\U\\1",res,perl=T)
}

对于在此过程中保留可能无法预测的缩写(特别是观察 5 中不常见的缩写)的稳健方法有什么想法吗?

【问题讨论】:

  • 我认为您可能需要一些后缀列表才能将 LLC, TR 排除在匹配之外并且不用于大写中
  • 除了@akrun 的建议,你试过stringi 包中的stri_trans_totitle() 吗?
  • @lawyeR 这也应该给出同样的问题。我试过了:-)
  • @lawyeR 是stringi 的开发版吗?我在documentation 中没有看到它
  • 是的,请查看第 132 页的 pdf 文档

标签: regex r


【解决方案1】:

这是一个使用正则表达式将字符串转换为标题大小写的函数(改编自 @BenBolker's answer to a question I asked on SO a while back)。

编写该函数以便您可以传递一个名为exceptions 的参数,该参数处理像GVM 这样的特殊情况。我不确定这是否足够灵活以满足您的需求,因为您必须对异常进行硬编码,但我想我会发布它,看看是否有人可以提出改进建议。

dat = data.frame(owner1 = c("DXXXXX JOSEPH V JR","MIRNA NXXXXX","ADRIAN TXXXX",
                                    "CUTLER PXXXXXXXXX LLC","GVM PXXXXXXXXX LLC",
                                    "EARLENA RXXXXXXX","NATHANIEL TXXXXX","DXXXXXX DONNA",
                                    "LXXXX ELAINE E TR","SXXXXXX KIMBERLY"))

# Convert a string to title case
tc = function(strings, exceptions="\\b(gvm)\\b") {

  # Convert to title case, excluding terminal LLC, TR, etc.
  title.case = gsub("\\b([a-zA-Z])([a-zA-Z]+)*( LLC| TR| FBO| LP)?", 
                    "\\U\\1\\L\\2\\U\\3", strings, perl=TRUE)

  # Add a period after initials (presumed to be any lone capital letter)
  title.case = gsub(" ([A-Z]) ", " \\1\\. ", title.case)

  # Deal with exceptions
  title.case = gsub(exceptions, "\\U\\1", title.case, perl=TRUE, ignore.case=TRUE)

  return(title.case)
}

dat$title.case = tc(dat$owner1)

                  owner1            title.case
1     DXXXXX JOSEPH V JR   Dxxxxx Joseph V. Jr
2           MIRNA NXXXXX          Mirna Nxxxxx
3           ADRIAN TXXXX          Adrian Txxxx
4  CUTLER PXXXXXXXXX LLC Cutler Pxxxxxxxxx LLC
5     GVM PXXXXXXXXX LLC    GVM Pxxxxxxxxx LLC
6       EARLENA RXXXXXXX      Earlena Rxxxxxxx
7       NATHANIEL TXXXXX      Nathaniel Txxxxx
8          DXXXXXX DONNA         Dxxxxxx Donna
9      LXXXX ELAINE E TR    Lxxxx Elaine E. TR
10      SXXXXXX KIMBERLY      Sxxxxxx Kimberly

【讨论】:

  • 我正在使用的.simpleCap 函数的矢量化版本的大道具,这大大加快了我的代码速度。我最终确定了与您提出的功能接近的功能。我的更量身定做;概括地说,我可能也会传递 exceptionsinitialize 参数。
  • 我还使用以下方法来确定周围存在什么样的 2 字母辅音短语并逐个处理它们:regmatches(string,regexpr("\\b[B-DF-HJ-NP-TV-XZ]{2}\\b",string))(不幸的是,一揽子例外是不合适的,因为大量的缩写,如 Jr、Sr、Co、Sc(学校)、Ch(教堂)和一些越南名字,如 Ng 等)
猜你喜欢
  • 2020-11-01
  • 2012-12-01
  • 2019-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
相关资源
最近更新 更多