次のような文字列の大きなベクトルがあります。
d <- c("herb", "market", "merchandise", "fun", "casket93", "old", "herbb", "basket", "bottle", "plastic", "baskket", "markket", "pasword", "plastik", "oldg", "mahagony", "mahaagoni", "sim23", "asket", "trump" )
同じベクトル d から各文字列に対して同様の文字列を取得したくありません。
1. 文字列ごとに、数字が存在する場合やアルファベット文字数が 5 未満の場合に完全一致を強制するなどの特定のルールに基づいて、他のすべての文字列文字列との編集距離を計算します
。文字列とともにデータフレーム dist。
3. 距離 < 3 に基づいて dist をサブセット化します。
4. 同様の文字列を折りたたんで、新しい列として元のデータフレームに追加します。
stringr
とstringdist
パッケージを使用しています
d <-as.data.frame(d)
M <- nrow(d)
Dist <- data.frame(matrix(nrow=M, ncol=2))
colnames(Dist) <- c("string" ,"dist")
Dist$string <- d$d
d$sim <- character(length=M)
require(stringr)
require(stringdist)
for (i in 1:M){
# if string has digits or is of short size (<5) do exact matching
if (grepl("[[:digit:]]", d[i, "d"], ignore.case=TRUE) == TRUE || str_count(d[i, "d"], "[[:alpha:]]") < 5){
Dist$dist <- stringdist(d[i, "d"], d$d, method="lv", maxDist=0.000001) # maxDist as fraction to force exact matching
# otherwise do approximate matching
} else {
Dist$dist <- stringdist(d[i, "d"], d$d, method="lv", maxDist=3)
}
# subset similar strings (with edit distance <3)
subDist <- subset(Dist, dist < 3 )
# add to original data.frame d
d[i, "sim"] <- paste(as.character(unlist(subDist$string)), collapse=", ")
}
ループを使用する代わりに、プロシージャをベクトル化することは可能ですか? 文字列の非常に大きなベクトルがあるためstringdistmatrix
、メモリの制限により、ベクトル全体を使用して距離行列を計算することはできません。ループは大きなデータに対しては正常に機能しますが、非常に低速です。