Fusionando dos marcos de datos usando coincidencia de cadenas difusa / aproximada en R

DESCRIPCIÓN

Tengo dos conjuntos de datos con información que necesito fusionar. Los únicos campos comunes que tengo son cadenas que no coinciden perfectamente y un campo numérico que puede ser sustancialmente diferente

La única forma de explicar el problema es mostrarle los datos. Aquí está a.csv y b.csv . Estoy intentando fusionar B con A.

Hay tres campos en B y cuatro en A. Nombre de la compañía (Solo archivo A), Nombre del fondo, Clase de activos y Activos. Hasta ahora, mi atención se ha centrado en intentar hacer coincidir los nombres de los fondos mediante el reemplazo de palabras o partes de las cadenas para crear coincidencias exactas y luego usar:

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

Sin embargo, esto solo me lleva a un 30% de coincidencia. El rest lo tengo que hacer a mano.

Los activos son un campo numérico que no siempre es correcto en ambos y puede variar enormemente si el fondo tiene activos bajos. Asset Class es un campo de cadena que “generalmente” es el mismo en ambos archivos, sin embargo, hay discrepancias.

Agregando a la complicación están las diferentes series de fondos, en el Archivo B. Por ejemplo:

Valor canadiense AGF

AGF Canadian Value-D

En estos casos, tengo que elegir el que no está escrito, o elegir el que se llama “A”, “-A” o “Asesor” como la coincidencia.

PREGUNTA

¿Cuál dirías que es el mejor enfoque? Este ejercicio es algo que tengo que hacer mensualmente y emparejarlos manualmente es increíblemente lento. Los ejemplos de código serían instrumentales.

IDEAS

Un método que creo que puede funcionar es normalizar las cadenas basadas en la primera letra en mayúscula de cada palabra en la cadena. Pero no he podido averiguar cómo sacar eso usando R.

Otro método que consideré fue la creación de un índice de coincidencias basado en una combinación de activos, nombre de fondos, clase de activos y compañía. Pero, de nuevo, no estoy seguro de cómo hacer esto con R. O, para el caso, si es posible.

¡Ejemplos de código, comentarios, pensamientos y dirección son muy apreciados!

La coincidencia aproximada de cadenas no es una buena idea ya que una coincidencia incorrecta invalidaría todo el análisis. Si los nombres de cada fuente son los mismos cada vez, la creación de índices también me parece la mejor opción. Esto se hace fácilmente en R:

Supongamos que tiene los datos:

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

Cree un índice de nombres para cada fuente una vez, tal vez utilizando pmatch, etc. como punto de partida y luego valide 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)) 

Luego, para cada combinación de ejecución, utilice:

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

Que nos daría:

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

Se recomienda encarecidamente usar el paquete dgrtwo / fuzzyjoin . stringdist_inner_join(a,b, by="Fund.Name")

Una sugerencia rápida: intente hacer algunas coincidencias en los diferentes campos por separado antes de usar merge. El enfoque más simple es con la función pmatch , aunque R no tiene escasez de funciones de coincidencia de texto (por ejemplo, agrep ). Aquí hay un ejemplo simple:

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

Para su conjunto de datos, esto coincide con todos los nombres de fondos 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 

Una vez que cree las coincidencias, puede fusionarlas fácilmente usando aquellas en su lugar.

También soy un local de Canadá, reconozco los nombres de los fondos.

Esto es difícil ya que cada uno de los proveedores de datos elige su propio formulario para los nombres de los fondos individuales. Algunos utilizan una estructura diferente, como todos los finales, ya sea en Fund o Class, otros están por todos lados. Cada uno parece elegir sus propios short-forms también y estos cambian regularmente.

Es por eso que muchas personas como usted lo hacen a mano regularmente. Algunas de las firmas consultoras enumeran índices para vincular varias fonts, ¿no está seguro de haber explorado esa ruta?

Como Shane y Marek señalaron, esta es una tarea coincidente más que una unión directa. Muchas compañías están luchando con esto. Estoy en el medio de mi trabajo en esto …

Arrendajo

    Intereting Posts