Mesclar dois frameworks de dados usando correspondência de strings aproximada / aproximada em R

DESCRIÇÃO

Eu tenho dois conjuntos de dados com informações que preciso mesclar. Os únicos campos comuns que tenho são strings que não combinam perfeitamente e um campo numérico que pode ser substancialmente diferente

A única maneira de explicar o problema é mostrar os dados. Aqui está a.csv e b.csv . Eu estou tentando mesclar B para A.

Existem três campos em B e quatro em A. Nome da Empresa (Somente Arquivo A), Nome do Fundo, Classe do Ativo e Ativos. Até agora, meu foco tem sido tentar comparar os Nomes dos Fundos substituindo palavras ou partes das sequências para criar correspondências exatas e, em seguida, usando:

a <- read.table(file = "http://bertelsen.ca/R/a.csv",header=TRUE, sep=",", na.strings=F, strip.white=T, blank.lines.skip=F, stringsAsFactors=T) b <- read.table(file = "http://bertelsen.ca/R/b.csv",header=TRUE, sep=",", na.strings=F, strip.white=T, blank.lines.skip=F, stringsAsFactors=T) merge(a,b, by="Fund.Name") 

No entanto, isso só me leva a cerca de 30% de correspondência. O resto eu tenho que fazer à mão.

Ativos é um campo numérico que nem sempre é correto em nenhum deles e pode variar muito se o fundo tiver ativos baixos. Classe de Ativo é um campo de string que é “geralmente” o mesmo em ambos os arquivos, no entanto, existem discrepâncias.

Somando-se a complicação estão as diferentes séries de fundos, no Arquivo B. Por exemplo:

Valor Canadense AGF

Valor canadense AGF-D

Nesses casos, eu tenho que escolher o que não é seriado, ou escolher aquele que é chamado “A”, “-A” ou “Advisor” como a correspondência.

QUESTÃO

O que você diria que é a melhor abordagem? Este exercício é algo que eu tenho que fazer em uma base mensal e combinando-os manualmente é incrivelmente demorado. Exemplos de código seriam instrumentais.

IDÉIAS

Um método que eu acho que pode funcionar é normalizar as seqüências de caracteres com base na primeira letra maiúscula de cada palavra na seqüência de caracteres. Mas eu não consegui descobrir como fazer isso usando R.

Outro método que considerei foi criar um índice de correspondências baseado em uma combinação de ativos, nome do fundo, class do ativo e empresa. Mas, novamente, não tenho certeza de como fazer isso com a R. Ou, se é que isso é possível.

Exemplos de código, comentários, pensamentos e direção são muito apreciados!

A correspondência aproximada de cadeias não é uma boa ideia, pois uma correspondência incorreta invalida toda a análise. Se os nomes de cada fonte são os mesmos a cada vez, então criar índices também é a melhor opção para mim. Isso é feito facilmente em R:

Suponha que você tenha os dados:

 a< -data.frame(name=c('Ace','Bayes'),price=c(10,13)) b<-data.frame(name=c('Ace Co.','Bayes Inc.'),qty=c(9,99)) 

Crie um índice de nomes para cada fonte uma vez, talvez usando pmatch etc. como ponto de partida e depois valendo manualmente.

 a.idx< -data.frame(name=c('Ace','Bayes'),idx=c(1,2)) b.idx<-data.frame(name=c('Ace Co.','Bayes Inc.'), idx=c(1,2)) 

Então, para cada mesclagem de execução usando:

 a.rich< -merge(a,a.idx,by="name") b.rich<-merge(b,b.idx,by="name") merge(a.rich,b.rich,by="idx") 

O que nos daria:

  idx name.x price name.y qty 1 1 Ace 10 Ace Co. 9 2 2 Bayes 13 Bayes Inc. 99 

É altamente recomendável usar o pacote dgrtwo / fuzzyjoin . stringdist_inner_join(a,b, by="Fund.Name")

Uma sugestão rápida: tente fazer alguma correspondência nos diferentes campos separadamente antes de usar a mesclagem. A abordagem mais simples é com a function pmatch , embora R não tenha escassez de funções de correspondência de texto (por exemplo, agrep ). Aqui está um exemplo simples:

 pmatch(c("med", "mod"), c("mean", "median", "mode")) 

Para o seu dataset, isso corresponde a todos os nomes de fundos de a :

 > nrow(merge(a,b,x.by="Fund.Name", y.by="Fund.name")) [1] 58 > length(which(!is.na(pmatch(a$Fund.Name, b$Fund.name)))) [1] 238 

Depois de criar correspondências, você pode facilmente mesclá-las usando essas.

Eu também sou canadense, reconheço os nomes dos fundos.

Isso é difícil, pois cada um dos provedores de dados escolhe seu próprio formulário para os nomes dos fundos individuais. Alguns usam estrutura diferente como todo o fim em qualquer fundo ou class outros estão por todo o lugar. Cada um parece também escolher suas próprias formas curtas e elas mudam regularmente.

É por isso que muitas pessoas como você estão fazendo isso à mão regularmente. Algumas empresas de consultoria listam índices para vincular várias fonts, não tendo certeza se você explorou essa rota?

Como Shane e Marek apontaram, esta é uma tarefa mais do que uma junit direta. Muitas empresas estão lutando com isso. Eu estou no meio do meu trabalho sobre isso …

Jay