Cree una ID única mediante la coincidencia aproximada de nombres (a través de un acuerdo con R)

Utilizando R, estoy intentando hacer coincidir los nombres de las personas en un conjunto de datos estructurado por año y ciudad. Debido a algunos errores de ortografía, la coincidencia exacta no es posible, por lo que estoy tratando de usar agrep () para hacer coincidir los nombres de coincidencia.

Un fragmento de muestra del conjunto de datos se estructura de la siguiente manera:

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")) ))

La versión limpia:

  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

Me gustaría verificar en cada ciudad por separado, si hay candidatos que aparecen en varios años. P.ej. en el ejemplo,

PAULO CEZAR FERREIRA DE ARAUJO

PAULO CESAR FERREIRA DE ARAUJO

Aparece dos veces (con un error de ortografía). A cada candidato en todo el conjunto de datos se le debe asignar un ID de candidato numérico único. El conjunto de datos es bastante grande (5500 ciudades, aproximadamente 100 000 entradas), por lo que sería útil una codificación algo eficiente. ¿Alguna sugerencia sobre cómo implementar esto?

EDITAR: Aquí está mi intento (con la ayuda de los comentarios hasta ahora) que es muy lento (ineficiente) para lograr la tarea en cuestión. ¿Alguna sugerencia en cuanto a mejoras a esto?

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)

EDIT 2: Ahora corriendo a buena velocidad. El problema fue la comparación de muchos factores en cada paso (Gracias por señalarlo, Blue Magister). Al reducir la comparación a solo los candidatos de un grupo (es decir, una ciudad), se ejecuta el comando en 5 segundos para 80,000 líneas, una velocidad con la que puedo vivir.

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)

Respuestas a la pregunta(2)

Su respuesta a la pregunta