2016-04-13 18 views
1

Ich arbeite derzeit an einem Programmierprojekt in R (für die Schule) und ich verwende einen Datensatz aus einer großen Anzahl von LastFm Benutzer (eine Anwendung, die Daten sammelt, wenn Sie eine verwenden Media Player). Ich möchte an einer eventuellen Verbindung zwischen 2 Variablen im Datensatz arbeiten, die der "Spitzname" und der "echte Name" sind. Um dies zu tun, möchte ich eine Variable berechnen, die die Ähnlichkeitsrate zwischen den Charakteren darstellt.Vergleichen Zeichenfolge in R

Als Beispiel nimmt eine Person (unabhängig von den anderen Variablen):

name = 'chris meller' 
nickname = 'mellertime' 

Bisher versuchten die Saiten, um zu sortieren, um für gleiche Zeichen nacheinander zu prüfen, aber ich bin hier fest . Was ich gefunden habe, ist nur eine Möglichkeit zu überprüfen, ob "Name" in "Nickname" mit verschiedenen Arten von Funktionen vorhanden ist.

>paste(sort(unlist(strsplit(name, ""))), collapse = "") 
[1] "eeeillmmrt" 
>paste(sort(unlist(strsplit(nickname, ""))), collapse = "") 
[1] " ceehillmrrs" 

Was würde ich wissen, ob es einen Weg gibt, um die Anzahl der gleichen Buchstaben zwischen zwei Zeichenketten zu zählen, unabhängig von der Reihenfolge?

Ich mag mit so etwas Ende:

function(a,b) 
[1] 0.63 
# a,b are 2 character strings 

, wo das Ergebnis zwischen den beiden Saiten, dividiert durch die Anzahl der Zeichen in dem wirklichen Namen das Verhältnis der Anzahl von identischen Zeichen ist.

+1

Count Buchstaben mit 'Tabelle (strsplit ('eeeillmmrt', '') [[1]])', aber Bearbeitungsentfernung (siehe '? adist') wäre wahrscheinlich nützlicher. – alistaire

+0

@alistaire Danke für den Tipp, ich habe nie Levenshtein Entfernung gehört, die in adist verwendet wird, wenn ich meinen Weg nicht finden kann, werde ich wahrscheinlich etwas mit Levenshtein machen. –

+0

@allstaire, könnten Sie mehr Einblick in die Implementierung von 'adist' geben? Ich konnte es nicht bekommen, was das OP suchte. Ich habe sogar versucht, ein bisschen in das "stringdist" -Paket zu gehen, konnte aber keine passende Lösung finden. –

Antwort

0

Try this:

SimilarityRatio <- function(wholeName, nickname, matchCase) { 

    n1 <- sort(strsplit(paste(strsplit(wholeName, " ")[[1]], collapse = ""), "")[[1]]) 
    n2 <- sort(strsplit(paste(strsplit(nickname, " ")[[1]], collapse = ""), "")[[1]]) 

    if (!matchCase) { 
     n1 <- tolower(n1) 
     n2 <- tolower(n2) 
    } 

    MyLen <- tempLen <- length(n1) 
    j <- 1L 
    numMatch <- 0L 

    while (j <= tempLen) { 
     test1 <- n1[j] %in% n2 
     if (test1) { 
      myRemove <- min(which(n2 %in% n1[j])) 
      n1 <- n1[-j] 
      n2 <- n2[-myRemove] 
      numMatch <- numMatch + 1L 
      tempLen <- tempLen - 1L 
     } else { 
      j <- j+1L 
     } 
    } 

    numMatch/MyLen 
} 

Im Folgenden sind einige Testfälle:

> SimilarityRatio("chris meller", "mellertime", FALSE) 
[1] 0.6363636 
> SimilarityRatio("SuperMan3000", "The3Musketeers", FALSE) 
[1] 0.5 
> SimilarityRatio("SuperMan3000", "The3Musketeers", TRUE) 
[1] 0.4166667 
> SimilarityRatio("should a garbage collection be performed immediately", "same expression can vary considerably depending on whether", FALSE) 
[1] 0.7608696 
+0

Mann es funktioniert perfekt, ich bin so dankbar! Danke vielmals. –

Verwandte Themen