1

フルネームのセットからサフィックスのセットを削除したいと思います(サフィックスとフルネームの両方が文字ベクトルです)。for()これは2つのループとで非常に簡単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)"すべてのサフィックスを持つようなものです。

のように1つの文字列から複数のサフィックスを削除したいように思われるので、の"larry inc incorp"ようなものが必要です"( suffix1| suffix2)+$"

次に、それをに適用するだけですnames.full(「moe」を「moemoney」に変更して、「最初の単語」の解決策が失敗する場所を示します)。次のようになります。

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おそらくより適切ですgsubgsub通常、単語内のパターンのいくつかのインスタンスを置き換えるために使用されます)。

于 2011-07-19T01:23:41.523 に答える
1

本当にforループを使用する必要がありますか?gsubでバックリファレンスを使用して、必要なものを抽出できるはずです。

  • \\w0〜9、A〜Z、およびa〜zの範囲の任意の文字に一致します。
  • 前の+文字と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 に答える