Estou trabalhando em R
Meus dados possuem 500.000 linhas, mas um pequeno exemplo é usado aqui.
Tenho alguns dados sobre funcionários que trabalham em escolas. Algumas pessoas trabalham em uma escola, outras em duas, outras em três, etc. Cada escola em que trabalham é uma linha de dados.
As escolas nem sempre registram os primeiros nomes iguais para um indivíduo. por exemplo, uma escola registra como Will, outra como William.
Também tenho esta suposição: para um indivíduo que trabalha em mais de uma escola, o segundo nome e a data de nascimento são sempre registrados iguais em cada escola.
Com base na semelhança do primeiro nome, quero uma maneira de identificar as pessoas que provavelmente são a mesma pessoa e, em seguida, atribuir-lhes um ID.
Haverá algum tipo de corte, por exemplo, greg e griffin provavelmente não serão a mesma pessoa, embora compartilhem as mesmas duas primeiras letras.
dados de amostra:
data_current <- data.frame(first_name = c("will", "william", "william", "laura", "jessica", "jessicalouise", "james", "greg", "griffin"),
last_name = c("smith", "smith", "smith", "maxwell", "maxwell", "maxwell", "lead", "jones", "jones"),
date_of_birth = c("2000-01-02","2000-01-02", "2000-01-02", "2007-01-02","2007-01-02","2007-01-02","1999-01-02","2004-01-02","2004-01-02"),
school_id = c(1, 2, 3, 4, 5, 6, 7, 8, 9))
primeiro nome | segundo nome | data de nascimento | id_escola |
---|---|---|---|
vai | ferreiro | 02/01/2000 | 1 |
William | ferreiro | 02/01/2000 | 2 |
William | ferreiro | 02/01/2000 | 3 |
Laura | maxwell | 02-01-2007 | 4 |
Jéssica | maxwell | 02-01-2007 | 5 |
jessicalouise | maxwell | 02-01-2007 | 6 |
James | liderar | 02/01/1999 | 7 |
Greg | Jones | 02-01-2004 | 8 |
grifo | Jones | 02-01-2004 | 9 |
dados desejados:
É provável que as três primeiras pessoas sejam a mesma pessoa, portanto recebam o mesmo person_id e assim por diante...
data_desired <- data.frame(first_name = c("will", "william", "william", "laura", "jessica", "jessicalouise", "james", "greg", "griffin"),
last_name = c("smith", "smith", "smith", "maxwell", "maxwell", "maxwell", "lead", "jones", "jones"),
date_of_birth = c("2000-01-02","2000-01-02", "2000-01-02", "2007-01-02","2007-01-02","2007-01-02","1999-01-02","2004-01-02","2004-01-02"),
school_id = c(1, 2, 3, 4, 5, 6, 7, 8, 9),
person_id = c(1, 1, 1, 2, 3, 3, 4, 5, 6))
primeiro nome | segundo nome | data de nascimento | id_escola | id_pessoa |
---|---|---|---|---|
vai | ferreiro | 02/01/2000 | 1 | 1 |
William | ferreiro | 02/01/2000 | 2 | 1 |
William | ferreiro | 02/01/2000 | 3 | 1 |
Laura | maxwell | 02-01-2007 | 4 | 2 |
Jéssica | maxwell | 02-01-2007 | 5 | 3 |
jessicalouise | maxwell | 02-01-2007 | 6 | 3 |
James | liderar | 02/01/1999 | 7 | 4 |
Greg | Jones | 02-01-2004 | 8 | 5 |
grifo | Jones | 02-01-2004 | 9 | 6 |
Alguém tem alguma sugestão de como resolver isso?
Aqui está uma possibilidade usando similaridade de strings. Funciona bem no seu exemplo porque você tem separação completa em seus dados. No entanto, com mais de 500 mil linhas, você pode encontrar alguns problemas com isso, mas pode começar:
Saída
Como funciona
Conforme mencionado nos comentários, isso pode ser complicado para nomes que possuem bigramas semelhantes, mas não são iguais. Esses casos serão difíceis de distinguir. Além disso, esta é apenas uma comparação lexical e provavelmente não funcionará bem para nomes abreviados. Por exemplo, como "Bob" é a abreviação de "Robert" ou "Dick" é a abreviação de "Richard".
Você também pode considerar o uso de outras medidas de similaridade de strings. Por exemplo, você pode especificar a similaridade Jaro–Winkler (
method = 'jw'
) com um peso (p = 0.10
). Isso ponderará os primeiros nomes que começam da mesma forma ("will" versus "william"), resultando em uma pontuação de similaridade mais alta e possível separação.