1

我想从一组全名中删除一组后缀(后缀和全名都是字符向量)。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
4

2 回答 2

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通常用于替换单词中的多个模式实例) 更合适。

于 2011-07-19T01:23:41.523 回答
1

你真的需要使用for循环吗?我认为您应该能够在 gsub 中使用反向引用来提取您想要的内容。

  • 匹配 0 - 9、A - Z 和 a - z 范围内的\\w任何字符。
  • 匹配前一个字符 1次+或多次。
  • 允许我们在()正则表达式后面引用任何内容。
  • 匹配任何字符的. 所有字符并*匹配前面的字符 0 次或更多次。

将以上所有内容放在一起给我们:

gsub("(\\w+)(.*)", "\\1", names.full)

> gsub("(\\w+)(.*)", "\\1", names.full)
[1] "tom"   "dick"  "harry" "larry" "curly"  "moe"   
于 2011-07-19T01:07:07.077 回答