我想从一组全名中删除一组后缀(后缀和全名都是字符向量)。使用两个for()
循环和gsub()
这很容易,但似乎应该有一种更有效的方法(在代码行和时钟周期中)。
我的第一个想法是rapply()
,但我无法让它发挥作用。也许for()
循环是最好的方法,但此时我对更好地理解rapply()
这是for()
循环版本。
names.full <- c("tom inc", "dick co", "harry incorp", "larry inc incorp", "curly", "moe")
suffix <- c("inc", "incorp", "incorporated", "co", "company")
suffix <- paste(" ", suffix, "$", sep = "")
# with loops
names.abbr <- names.full
for (k in seq(2)) {
for (i in seq(length(names.abbr))) {
for (j in seq(length(suffix))) {
names.abbr[i] <- gsub(suffix[j], "", names.abbr[i])
}
}
}
我失败的rapply()
版本。
# with rapply
inner.fun <- function(y, x) {
rapply(as.list(x), function(x) gsub(y, "", x), how = "replace")
}
names.abbr.fail <- unlist(rapply(as.list(suffix), inner.fun, x = names.full, how = replace))
出现以下错误:
> names.abbr.fail <- unlist(rapply(as.list(suffix), inner.fun, x = names.full, how = replace))
Error in match.arg(how) : 'arg' must be NULL or a character vector
答案 0 :(得分:3)
在您的示例中,您最终只会移除除第一个单词之外的所有单词。这很容易用
完成sub(" .*$", "", names.full)
但更常见的regexpr模式类似于"(suffix1|suffix2)"
,它包含所有后缀。
由于您似乎想要从"larry inc incorp"
中删除一个字符串中的多个后缀,因此您需要"( suffix1| suffix2)+$"
之类的内容。
然后你可以简单地将它应用到names.full
(我将“moe”改为“moe money”以显示“第一个单词”解决方案失败的地方)。它看起来像这样:
names.full <- c("tom inc", "dick co", "harry incorp",
"larry inc incorp", "curly", "moe money")
suffix <- c("inc", "incorp", "incorporated", "co", "company")
pattern <- paste("(", paste(" ", suffix, collapse="|", sep=""), ")+$", sep="")
sub(pattern, "", names.full)
[1] "tom" "dick" "harry" "larry" "curly" "moe money"
顺便说一句,如果您不想替换除后缀之外的任何内容,sub
可能比gsub
更合适(gsub
通常用于替换一个单词中的模式的几个实例。
答案 1 :(得分:1)
你真的需要使用for循环吗?我认为你应该能够在gsub中使用back引用来提取你想要的东西。
\\w
匹配范围0 - 9,A - Z和a - z中的任何字符。 +
与之前的字符匹配1次或更多次。()
允许我们返回引用后面的内容
正则表达式。.
匹配任何字符,所有字符与*
匹配
前一个字符0次或更多次。将上述所有内容放在一起给了我们:
gsub("(\\w+)(.*)", "\\1", names.full)
> gsub("(\\w+)(.*)", "\\1", names.full)
[1] "tom" "dick" "harry" "larry" "curly" "moe"