> 800k 行のデータセットがあります (例):
id fieldA fieldB codeA codeB
120 Similar one addrs example1 929292 0006
3490 Similar oh addrs example3 929292 0006
2012 CLOSE CAA addrs example10232 kkda9a 0039
9058 CLASE CAC addrs example01232 kkda9a 0039
9058 NON DONE addrs example010193 kkda9a 0039
48848 OOO AD ADDD addrs example18238 uyMMnn 8303
フィールド ID は一意の ID です。フィールド codeA と codeB は同じでなければなりませんが、フィールド fieldA と fieldB にはレーベンシュタイン距離または同様の関数が必要です。それに基づいて、どの行が非常に似ているかを見つける必要があります。出力は、次の行にある可能性があります。
codeA codeB Similar
929292 0006 120;3490
kkda9a 0039 2012;9058
kkda9a 0039 9058
uyMMnn 8303 48848
コード A とコード B のような 2 つの制約がある場合、このような大きなデータセットの距離行列は機能せず、あまり意味がありません。1つのアプローチは、codeA-codeBで分割するplyr関数になると思いますが、その後行き詰まっています
明確にするために、fieldAとfieldB の両方で類似性が高く、codeAとcodeB で完全に一致するすべての行をグループ化したいと考えています。
編集:
David DeWert のアイデアに従って、この行に沿った何かが各 codeA-codeB グループで機能するように見えます。
library(stringdist)
clustering<-function(x){
if(nrow(x)>1){{d<-stringdistmatrix(paste(x$fieldA,x$fieldB),paste(x$fieldA,x$fieldB),method = "qgram")
rownames(d)<-x$id
hc <- hclust(as.dist(d))
#I need to evaluate correctly this cutting
res<-cutree(hc,h=5)
#This returns a list, one element for each cluster found and a named vector inside with the elements
return(res)
}else{
res<-1
names(res)<-x$id
return(res)
}
}
ここで、データフレームを codeA-codeB グループに分割し、この関数をそれらに適用する方法を見つける必要があります。
EDIT2:
以前の関数クラスタリングと plyr パッケージを使用して、これに対して「十分な」アプローチを管理しました。
result<-dlply(testDF,.(codeA,codeB),clustering)
これにより、次のような「codeA、codeBによるグループ」のそれぞれを含むリストが作成されます。
$`929292.0006`
120 3490
1 1
$kkda9a.0039
2012 9058 9058
1 1 2
$uyMMnn.8303
48848
1
attr(,"split_type")
[1] "data.frame"
attr(,"split_labels")
codeA codeB
1 929292 0006
2 kkda9a 0039
3 uyMMnn 8303
これは、codeA と codeB によって作成されたグループを fieldA と fieldB で効果的にクラスター化します。これで目的の出力が得られませんが、より良い解決策が得られないため、やらなければなりません。これに対する私の最大の不満は、plyr 関数の性質上、グループごとに複数の行を取得できないことです (これは完全に理にかなっています)。そのため、データフレームの代わりにリストを結果として使用する必要があります。問題は、データセットが非常に大きく (このように)、plyr がうまく機能しない場合に発生します...そして代替の dplyr パッケージはリストの結果と互換性がありません...まあ。