对人名进行资本化(占'和 - )

时间:2015-09-24 11:35:15

标签: r capitalize

我有一个(人类)名字的矢量,都是大写字母:

names <- c("FRIEDRICH SCHILLER", "FRANK O'HARA", "HANS-CHRISTIAN ANDERSEN")

到目前为止,为了去资本化(仅限首字母大写),我正在使用

simpleDecap <- function(x) {
  s <- strsplit(x, " ")[[1]] 
  paste0(substring(s, 1,1), tolower(substring(s, 2)), collapse=" ")
  }
sapply(names, simpleDecap, USE.NAMES=FALSE)
# [1] "Friedrich Schiller"         "Frank O'hara"         "Hans-christian Andersen"

但我还要考虑'-。当然,使用s <- strsplit(x, " |\\'|\\-")[[1]]会找到正确的字母,但随后崩溃'-会丢失。因此,我试过

simpleDecap2 <- function(x) {
  for (char in c(" ", "\\-", "\\'")){
    s <- strsplit(x, char)[[1]] 
    x <-paste0(substring(s, 1,1), tolower(substring(s, 2)), collapse=char)
  } return x
  }

sapply(names,simpleDecap,USE.NAMES = FALSE)

但当然,情况更糟,因为结果是一个接一个地分开:

sapply(names, simpleDecap2, USE.NAMES=FALSE)
# [1] "Friedrich schiller"      "Frank o'Hara"            "Hans-christian andersen"

我认为正确的方法会根据s <- strsplit(x, " |\\'|\\-")[[1]]进行拆分,但paste=就是问题。

2 个答案:

答案 0 :(得分:6)

这似乎有效,使用Perl兼容的正则表达式:

gsub("\\b(\\w)([\\w]+)", "\\1\\L\\2", names, perl = TRUE)

\L将以下匹配组转换为小写。

答案 1 :(得分:0)

虽然我同意Perl regexp是更好的解决方案,但simpleDecap2方法并不是那么遥远。

simpleDecap3 <- function(x) {
    x <- tolower(x)
    for (char in c(" ", "-", "'")){
        s <- strsplit(x, char)[[1]] 
        x <-paste0(toupper(substring(s, 1,1)), substring(s, 2), collapse=char)
    } 
    x
}

也就是说,将整个名称改为小写,然后将“”,“ - 或”“之后的第一个字母大写。不像正则表达式那样美观,而且很可能不那么健壮,但只需对原始代码进行微小更改即可完成工作。