2010-02-09 28 views
9

DESCRIPCIÓNla fusión de dos tramas de datos utilizando la coincidencia de cadenas Fuzzy/aproximado en R

Tengo dos conjuntos de datos con la información que necesito para fusionarse. 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 combinar B con A.

Hay tres campos en B y cuatro en A. Nombre de la empresa (archivo A solamente), Nombre del fondo, Clase de activos y Activos. Hasta ahora, mi atención se ha centrado en tratar de coincidir con los nombres de fondos mediante la sustitución de palabras o partes de las cuerdas para crear coincidencias exactas y luego 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") 

Sin embargo, esto sólo me lleva a alrededor de 30% a juego. El resto lo tengo que hacer a mano.

Los activos son un campo numérico que no siempre es correcto en cualquiera de los dos y puede variar mucho si el fondo tiene pocos activos. Asset Class es un campo de cadena que "generalmente" es el mismo en ambos archivos, sin embargo, hay discrepancias.

Agregando a la complicación son las diferentes series de fondos, en el archivo B. Por ejemplo:

AGF Valor canadiense

AGF canadiense Valor-D

En estos casos, Tengo que elegir el que no está escrito, o elegir el que se llama "A", "-A", o "Asesor" como el partido.

PREGUNTA

Cuál diría usted 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.

FIN DE

Un método que creo que puede funcionar es la normalización de las cuerdas sobre la base de la primera letra en mayúscula de cada palabra de 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 fondo, 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.

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

+1

Si hablamos de coincidencia de cadenas, entonces '? Agrep' (en el paquete básico). – Marek

+1

Sería genial si puede hacer que los datos sean parte de la publicación para que podamos usar el ejemplo algunos años después de la publicación. Gracias. – Jochem

+0

de hecho algunos años más tarde y los datos no están allí –

Respuesta

2

cadena aproximada coincidencia 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 I:

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

construir un índice de nombres para cada fuente de una sola vez, tal vez usando pmatch etc. como punto de partida y luego validar 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 correr usando:

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

lo cual nos daría:

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

El problema es más cuando los nombres son más sucios que eso. Diga cuándo la primera palabra puede o no ser corta y cuándo el resto de las palabras puede ser corto o no. Esta forma breve no es consistente dentro de un solo nombre o entre nombres. – Jay

7

Una sugerencia rápida: tratar de hacer algo de juego en los diferentes campos por separado antes de usar fusionar. 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í está un ejemplo sencillo:

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

Para el conjunto de datos, esto coincide con todos los nombres de los 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 creada partidos, puede combinar fácilmente entre sí mediante los que en su lugar.

+0

Gracias, Shane, tus sugerencias siempre son útiles; echaré un vistazo a estas dos y te contaré cómo funcionó. –

+0

Sí definitivamente, excelentes consejos Shane. – Jay

+3

El problema es más cuando los nombres son más sucios que eso. Diga cuándo la primera palabra puede o no ser corta y cuándo el resto de las palabras puede ser corto o no. Esta forma breve no es consistente dentro de un solo nombre o entre nombres. – Jay

1

Soy también local de Canadá, reconozco los nombres de los fondos.

Esto es difícil ya que cada uno de los proveedores de datos elige su propia forma 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 manualmente de forma regular. Algunas de las firmas consultoras enumeran índices para vincular varias fuentes, ¿no está seguro de haber explorado esa ruta?

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

Jay

+0

Es frustrante. Estoy realmente sorprendido de que no tengan códigos asignados. La nomenclatura no está del todo estandarizada e incluso las clases de activos no coinciden de un proveedor al siguiente para el mismo año, y mucho menos el mismo mes.Si está trabajando en esto, me encantaría tener la oportunidad de analizarlo con más detalle: brandon AT bertelsen dot ca soy yo. –

+1

Definitivamente, algunos tienen códigos, pero son identificadores solo en sus propios sistemas ... Me gustaría tener la oportunidad de analizar y colaborar también. Voy a llamarte un correo electrónico en breve. – Jay

+1

Parece que solo puedo comentar mi propia respuesta ... , así que estoy de acuerdo con jmoy, uno debe construir un índice (id) para unir las diferentes fuentes. La clave es crear estos índices;) algunas cosas estándar funcionan y otras no. Es difícil. ¿Hay algún integrador de datos experimentado que quizás sepa algo que algunos de nosotros no conocemos? Concordancia aproximada y todos los alrededores que son la forma más automática que he encontrado para comenzar a abordar problemas como estos. – Jay

Cuestiones relacionadas