Utwórz unikalny identyfikator za pomocą rozmytego dopasowania nazw (za pomocą polecenia agrep przy użyciu R)

Korzystając z R, próbuję dopasować nazwiska osób w zbiorze danych uporządkowanym według roku i miasta. Z powodu pewnych błędów ortograficznych dokładne dopasowanie nie jest możliwe, więc próbuję użyć funkcji agrep () do nazw dopasowanych rozmytych.

Przykładowa porcja zestawu danych ma następującą strukturę:

df <- data.frame(matrix( c("1200013","1200013","1200013","1200013","1200013","1200013","1200013","1200013",                             "1996","1996","1996","1996","2000","2000","2004","2004","AGUSTINHO FORTUNATO FILHO","ANTONIO PEREIRA NETO","FERNANDO JOSE DA COSTA","PAULO CEZAR FERREIRA DE ARAUJO","PAULO CESAR FERREIRA DE ARAUJO","SEBASTIAO BOCALOM RODRIGUES","JOAO DE ALMEIDA","PAULO CESAR FERREIRA DE ARAUJO"), ncol=3,dimnames=list(seq(1:8),c("citycode","year","candidate")) ))

Zgrabna wersja:

  citycode year                      candidate
1  1200013 1996      AGUSTINHO FORTUNATO FILHO
2  1200013 1996           ANTONIO PEREIRA NETO
3  1200013 1996         FERNANDO JOSE DA COSTA
4  1200013 1996 PAULO CEZAR FERREIRA DE ARAUJO
5  1200013 2000 PAULO CESAR FERREIRA DE ARAUJO
6  1200013 2000    SEBASTIAO BOCALOM RODRIGUES
7  1200013 2004                JOAO DE ALMEIDA
8  1200013 2004 PAULO CESAR FERREIRA DE ARAUJO

Chciałbym sprawdzić w każdym mieście osobno, czy są kandydaci pojawiający się za kilka lat. Na przykład. w przykładzie

PAULO CEZAR FERREIRA DE ARAUJO

PAULO CESAR FERREIRA DE ARAUJO

pojawia się dwa razy (z błędem pisowni). Każdemu kandydatowi w całym zestawie danych należy przypisać unikalny numeryczny identyfikator kandydata. Zbiór danych jest dość duży (5500 miast, ok. 100 tys. Wpisów), więc pomocne byłoby nieco wydajne kodowanie. Wszelkie sugestie dotyczące sposobu wdrożenia tego?

EDYCJA: Oto moja próba (z pomocą komentarzy do tej pory), która jest bardzo powolna (nieefektywna) w realizacji zadania. Jakieś sugestie dotyczące ulepszeń do tego?

f <- function(x) {matches <- lapply(levels(x), agrep, x=levels(x),fixed=TRUE, value=FALSE)
                  levels(x) <- levels(x)[unlist(lapply(matches, function(x) x[1]))]
                  x
                }

temp <- tapply(df$candidate, df$citycode, f, simplify=TRUE)
df$candidatenew <- unlist(temp)
df$spellerror <- ifelse(as.character(df$candidate)==as.character(df$candidatenew), 0, 1)

EDYCJA 2: Teraz działa z dobrą prędkością. Problem polegał na porównaniu wielu czynników na każdym kroku (dzięki za wskazanie tego, Blue Magister). Zmniejszenie porównania tylko do kandydatów w jednej grupie (np. Mieście) uruchamia polecenie w ciągu 5 sekund na 80 000 linii - prędkość, z którą mogę żyć.

df$candidate <- as.character(df$candidate)

f <- function(x) {x <- as.factor(x)
                  matches <- lapply(levels(x), agrep, x=levels(x),fixed=TRUE, value=FALSE)
                  levels(x) <- levels(x)[unlist(lapply(matches, function(x) x[1]))]
                  as.character(x)
                }

temp <- tapply(df$candidate, df$citycode, f, simplify=TRUE)
df$candidatenew <- unlist(temp)
df$spellerror <- ifelse(as.character(df$candidate)==as.character(df$candidatenew), 0, 1)

questionAnswers(2)

yourAnswerToTheQuestion