人名大写(占'和-)
Decapitalize human names (accounting for ' and -)
我有一个(人)名向量,全部大写:
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(名称,simpleDecap,USE.NAMES=FALSE)
但这当然更糟,因为结果一个接一个地分开:
sapply(names, simpleDecap2, USE.NAMES=FALSE)
# [1] "Friedrich schiller" "Frank o'Hara" "Hans-christian andersen"
我认为正确的做法是根据 s <- strsplit(x, " |\'|\-")[[1]]
拆分,但 paste=
才是问题所在。
这似乎可行,使用 Perl 兼容的正则表达式:
gsub("\b(\w)([\w]+)", "\1\L\2", names, perl = TRUE)
\L
将以下匹配组转换为小写。
虽然我同意 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
}
即把全名转小写,然后将“”、“-”或“'”后的第一个字母转为大写。不如正则表达式好看,而且很可能不如正则表达式那么健壮,但它只需对原始代码进行少量更改即可完成工作。
我有一个(人)名向量,全部大写:
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(名称,simpleDecap,USE.NAMES=FALSE)
但这当然更糟,因为结果一个接一个地分开:
sapply(names, simpleDecap2, USE.NAMES=FALSE)
# [1] "Friedrich schiller" "Frank o'Hara" "Hans-christian andersen"
我认为正确的做法是根据 s <- strsplit(x, " |\'|\-")[[1]]
拆分,但 paste=
才是问题所在。
这似乎可行,使用 Perl 兼容的正则表达式:
gsub("\b(\w)([\w]+)", "\1\L\2", names, perl = TRUE)
\L
将以下匹配组转换为小写。
虽然我同意 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
}
即把全名转小写,然后将“”、“-”或“'”后的第一个字母转为大写。不如正则表达式好看,而且很可能不如正则表达式那么健壮,但它只需对原始代码进行少量更改即可完成工作。