我有一个(人类)名字的矢量,都是大写字母:
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=
就是问题。
答案 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
}
也就是说,将整个名称改为小写,然后将“”,“ - 或”“之后的第一个字母大写。不像正则表达式那样美观,而且很可能不那么健壮,但只需对原始代码进行微小更改即可完成工作。