2016-08-10 9 views
0

In RI haben data wie dieseDer beste Weg, Strings

ID 
Peter 
peter 
peterr 
john 
johN 
JOhn 
... 

ich einfach vergleichen wollen alle, die Person zu sammeln, zum Beispiel alles, was der Name wie Peter haben sollte, so meine neue Daten-Set gesammelt werden wäre wie diese

ID 
Peter, peter, peterr 
john, johN, JOhn 
... 

Deshalb möchte ich einen Code schreiben, die peter, Peter, peterr nehmen und sie sammeln und ich möchte es für alle Namen zu tun.

Was ist der beste Weg, dies zu tun?

+1

"Peter" gegen "Peter" zu vergleichen ist eine Sache, das einzige Problem ist der Fall, aber "Peter" und "Peter" gleichzusetzen, ist ein ganz anderes. Sie müssten uns die ganze Logik für Namensvergleiche geben, wenn Sie eine sinnvolle Antwort wollen. –

Antwort

2

Die Funktion adist() berechnet die Levenshtein distance zwischen Streichern.

df1 <- data.frame(ID=c("Peter", "peter", "peterr", "john", "johN", "JOhn")) 
adist(df1$ID) 
    [,1] [,2] [,3] [,4] [,5] [,6] 
[1,] 0 1 2 5 5 5 
[2,] 1 0 1 5 5 5 
[3,] 2 1 0 6 6 6 
[4,] 5 5 6 0 1 2 
[5,] 5 5 6 1 0 3 
[6,] 5 5 6 2 3 0 

Kleinere Abstandswerte weisen auf eine größere Ähnlichkeit. Die Index- (Zeilen-) Nummer der sechs Wörter "Peter", "Peter" usw. innerhalb des Vektors df1$ID entspricht der Spalten-/Zeilennummer in der Matrix.

Die Programmieraufgabe besteht dann darin, die Paare zu identifizieren, die einen kleinen Abstand haben. Hier ist eine Möglichkeit, Paare mit minimalem Unterschied zu finden:

dm <- adist(df1$ID) 
dm <- dm*upper.tri(dm) 
which(dm == 1, arr.ind=TRUE) 
#  row col 
#[1,] 1 2 
#[2,] 2 3 
#[3,] 4 5 

Diese drei Paare (1,2), (2,3) und (4,5) bezeichnen die Indexnummer der Saiten, die berücksichtigt werden können, um sehr ähnlich sein. Das sind: "Peter" und "Peter", "Peter" und "Peter", sowie "John" und "JohN".

data.frame(apply(which(dm == 1, arr.ind=TRUE), 2, function(x) df1$ID[x])) 
# row col 
#1 Peter peter 
#2 peter peterr 
#3 john johN 

Die Ähnlichkeitsschwelle kann durch Verwendung von beispielsweise which(dm > 0 & dm < 3, arr.ind=TRUE) abgesenkt werden. Dies führt zu einer größeren Anzahl ähnlicher Paare.

0

Sie müssen eine Matrix von String-Abständen zwischen jedem Eintrag auf dieser Liste und jedem anderen Element auf dieser Liste erstellen ... es wird riesig sein. Dann vereinfachen Sie diese Liste basierend auf einer gewissen Akzeptanz ... zum Beispiel StringDistance <2.

entwarf ich dieses Skript genau das zu tun: https://github.com/mexindian/DataProcessing/blob/master/misspellingFixer.R Sehen Sie, wenn es Ihr Problem

-2

zwei alternative Vorschläge löst:

gsub() von stringr Paket. Zum Beispiel, wenn Sie Peter in Ihren Variable ID gleichzusetzen: kann

gsub("pet", "Peter", data, ignore.case = TRUE)

Diese Option langweilig sein, wenn Sie eine Reihe von Ebenen gleichzusetzen haben.

Eine Alternative, auf der Grundlage von @Amit Kohli Vorschlag, ist ein anderes Paket fuzzyjoin, das für Ihre Zwecke nützlich sein könnte.