2016-10-07 4 views
0

私はそうのように、私は一致したい長さの異なる2つの文字のベクトルを持つ2つのデータフレーム、持っている:私は要素を含むベクトルを返し、company.aにcompany.bを比較したいと思いますサブセットは、levenshtein距離を含むためにgrepを使用していますか?

company.a <- c("heinz", "hawkings mcgill", "heinz ketchup", "heinz vinegars", "davis and smith", "dell computers", "dell", "O organics", "organics") 

company.b <- c("heinz", "hawkings-mcgill", "oyster bay", "company x", "dell") 

をcompany.aにマッチしたcompany.bから。私はしかし、私がリターンで取得することは論理的でなければならない「サブセット」を示すエラーです

に大きなフレームのサブセットには、次のコードを使用して
match.comp <- subset(company.a, grep(paste(company.b, collapse = "|"), company.a, value = TRUE)). 

を試してみました。次の結果が欲しいです:

match <- c("heinz", "hawkings mcgill", "heinz", "heinz", "FALSE", "dell", "dell", FALSE, FALSE) 

エラーが発生した場合、明らかに私はgrepまたはサブセットについて何か不足しています。私は2つの質問があります:

  1. これを行うにはgrepが最適ですか?それとも別の方法がありますか?私は(A%in%B)アプローチを使って正確に一致することを知っていますが、文字列が完全に一致するとは保証できません。

  2. Grepは最初の試合を返しますが、例えばlevenshtein distanceで考えられた可能性のある試合をすべて抽出する方法がありますか?私はutilsパッケージ内のadist機能を認識していますが、grepと組み合わせることができるかどうかを知りたいのです。

何か助けやアドバイスをいただければ幸いです。ありがとう。

+0

'agrep'で得ることができますか?あなたの望む出力は不明です。 – alistaire

+0

@alistaireありがとう。 agrepはよさそうだ。私が望むのは、一致する要素が動作すればそれを返し、そうでなければ論理値を返すことです。これはもっと明確ですか? – jvalenti

答えて

1

adistまたはagrepを使用できますが、コストとカットオフポイントは非常に主観的です。この場合、希望結果は

d <- adist(company.b, company.a, partial = TRUE) 
d <- apply(d, 2, prop.table) # working with proportions instead of costs can be useful 

matches <- apply(d, 2, function(x){ 
    x <- setNames(x, company.b) 
    names(which.min(x[x < 0.05])) # set cutoff carefully 
}) 
matches <- sapply(matches, function(x){ifelse(is.null(x), NA, x)}) # clean out NULLs 

matches 
## [1] "heinz"   "hawkings-mcgill" "heinz"   "heinz"   NA    
## [6] "dell"   "dell"   NA    NA  
+0

これは本当に優れたソリューションです!私は本当に助けに感謝します。非常に大きなデータフレームの最適なカットオフポイントを把握するための手順についてアドバイスをしていますか?または少なくとも私はそれを把握するために見ることができる?再度、感謝します。 – jvalenti

+1

それはあなたが文字列について知っているものと、それに一致させるものに少し依存します。上記の例では、一致する文字列はほとんど短くなっていますので、文字列の削除コストなしで部分文字列に一致する 'partial = TRUE'を使用しましたが、削除コストを明示的に設定できます。ドキュメントを読んだり遊んだりできますが、手動で検査するには大きすぎるデータについては、手動で検査できるサブセットのエラー率をチェックします。モデル構築のトレーニングエラーに似ています。 – alistaire

+0

カットオフについてもう少し説明できますか?同じ文字の割合が5%未満のものと一致しますか? – jvalenti

2

これは部分的にあなたの要件を満たすことがあります

library(utils) 

company.a <- c("heinz", "hawkings mcgill", "heinz ketchup", "heinz vinegars", "davis and smith", "dell computers", "dell", "O organics", "organics") 
company.b <- c("heinz", "hawkings-mcgill", "oyster bay", "company x", "dell") 

limit <- 2 

res <- sapply(company.a, function(wa) { 
    d <- sapply(company.b, function(wb){ 
     adist(wb, wa) 
    }) 
    d <- d[d<=limit] 
    names(d) 
}) 

上記のコードは、最初の配列内の各単語に、二番目の配列内のすべての一致を抽出します。ここでは、Levenshteinの距離が「極限」であれば、2つの単語が一致します。

上記の一致の一部は、このような単純なものではありません。たとえば、 "heinz"が "heinz ketchup"に一致しなければならない場合、これにはLevenshteinの距離制限8が必要です。これは一般的には高すぎます。これらの場合に対処するために、より複雑な距離関数を構築する必要があります。

関連する問題