2010-02-09 2 views
9

DESCRIZIONEUnione di due dati frame utilizzando Fuzzy/approssimativa stringa corrispondente in R

ho due set di dati con le informazioni che ho bisogno di unire. Gli unici campi comuni che ho sono stringhe che non corrispondono perfettamente e un campo numerico che può essere sostanzialmente diverso

L'unico modo per spiegare il problema è mostrarti i dati. Ecco a.csv e b.csv. Sto cercando di unire B a A.

Ci sono tre campi in B e quattro in A. Nome società (solo file A), nome del fondo, classe di asset e attività. Finora, la mia attenzione si è concentrata sul tentativo di abbinare i nomi del Fondo con la sostituzione di parole o parti di stringhe per creare corrispondenze esatte e quindi utilizzando:

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

Tuttavia, questo mi porta solo a circa il 30% di corrispondenza. Il resto devo fare a mano.

Le risorse sono un campo numerico che non è sempre corretto in entrambi e può variare in modo anomalo se il fondo ha scarse risorse. Asset Class è un campo stringa che è "generalmente" lo stesso in entrambi i file, tuttavia, vi sono discrepanze.

Aggiunta alla complicazione sono diverse serie di fondi, in File B. Per esempio:

AGF Canadian Valore

AGF Canadian Value-D

In questi casi, Devo scegliere quello che non è seried, o scegliere quello che è chiamato "A", "-A" o "Advisor" come la corrispondenza.

DOMANDA

Cosa diresti è l'approccio migliore? Questo esercizio è qualcosa che devo fare su base mensile e abbinarli manualmente è incredibilmente dispendioso in termini di tempo. Esempi di codice sarebbero strumentali.

IDEE

Un metodo che penso possa funzionare è normalizzare le corde in base alla prima lettera maiuscola di ogni parola nella stringa. Ma non sono stato in grado di capire come farlo usando R.

Un altro metodo che ho preso in considerazione è stato la creazione di un indice di corrispondenze basato su una combinazione di risorse, nome del fondo, classe di attivi e società. Ma di nuovo, non sono sicuro di come farlo con R. O, se è per quello, se è possibile.

Esempi di codice, commenti, pensieri e direzione sono molto apprezzati!

+1

Se parliamo di corrispondenza delle stringhe, allora '? Agrep' (nel pacchetto base). – Marek

+1

Sarebbe bello se fosse possibile rendere i dati parte del post in modo da poter utilizzare l'esempio pochi anni dopo la pubblicazione. Grazie. – Jochem

+0

in effetti qualche anno dopo e i dati non ci sono –

risposta

2

string matching approssimativa non è una buona idea, dato che delle partite non corretta potrebbe invalidare l'intera analisi. Se i nomi di ogni fonte sono sempre gli stessi, allora anche la costruzione degli indici sembra l'opzione migliore per me. Questo è fatto facilmente in R:

Supponiamo di avere i dati:

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

costruire un indice dei nomi per ogni fonte di una volta, magari utilizzando pmatch ecc come punto di partenza e quindi convalidare 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)) 

Poi per ogni merge eseguito utilizzando:

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

che darebbe a noi:

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

Il problema è più quando i nomi sono più sporchi di quello. Dì quando la prima parola può o non può essere in forma breve e quando il resto delle parole può o non può essere in corto. Questo shortforming non è coerente all'interno di un singolo nome o di altri nomi. – Jay

7

Un suggerimento rapido: provare a fare un po 'di corrispondenza sui diversi campi separatamente prima di utilizzare l'unione. L'approccio più semplice è con la funzione pmatch, sebbene R non manchi di funzioni di corrispondenza del testo (ad esempio agrep).Ecco un semplice esempio:

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

Per il vostro set di dati, questo corrisponde a tutti i nomi del fondo di 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 volta creato le partite, si può facilmente unire insieme utilizzare quelli invece.

+0

Grazie Shane, i tuoi suggerimenti sono sempre utili - darò un'occhiata a questi due e ti faccio sapere come ha funzionato. –

+0

Sì, sicuramente, ottimi consigli Shane. – Jay

+3

Il problema è più quando i nomi sono più sporchi di quello. Dì quando la prima parola può o non può essere in forma breve e quando il resto delle parole può o non può essere in corto. Questo shortforming non è coerente all'interno di un singolo nome o di altri nomi. – Jay

1

Sono un cittadino canadese, riconosco i nomi dei fondi.

Questo è difficile poiché ciascuno dei fornitori di dati sceglie il proprio modulo per i singoli nomi di fondi. Alcuni usano strutture diverse come tutte le estremità in entrambi i fondi o in altre classi. Ognuno sembra scegliere le proprie forme corte e queste cambiano regolarmente.

Ecco perché così tante persone come te stanno facendo questo a mano regolarmente. Alcune società di consulenza elencano gli indici per collegare varie fonti, non sono sicuro se hai esplorato quella strada?

Come ha sottolineato Shane e Marek, si tratta di un compito di abbinamento più che di un join diretto. Molte aziende stanno lottando con questo. Sono nel bel mezzo del mio lavoro su questo ...

Jay

+0

È frustrante. Sono davvero sorpreso che non abbiano codici assegnati a loro. La nomenclatura non è affatto standardizzata e anche le classi di attività non corrispondono da un fornitore all'altro per lo stesso anno, per non parlare dello stesso mese.Se ci stai lavorando, mi piacerebbe avere l'opportunità di discuterne in modo più dettagliato: brandon AT bertelsen dot ca sono io. –

+1

Decisamente, alcuni hanno codici ma sono identificatori solo nei loro sistemi ... Mi piacerebbe l'opportunità di discutere e collaborare pure. Ti farò una breve email. – Jay

+1

Sembra che posso solo commentare la mia risposta .... quindi concordo con jmoy si dovrebbe contrarre un indice (id) da utilizzare per unire le diverse fonti. La chiave sta creando questi indici;) alcuni dei lavori standard funzionano in parte. È difficile. Ci sono degli integratori di dati sperimentati là fuori che forse sanno qualcosa che alcuni di noi potrebbero non sapere? Accoppiamento approssimativo e tutto ciò che è il modo più automatico che ho trovato per iniziare ad affrontare problemi come questi. – Jay