21

説明

マージする必要がある情報を含む 2 つのデータセットがあります。私が持っている唯一の共通フィールドは、完全に一致しない文字列と、実質的に異なる可能性がある数値フィールドです

問題を説明する唯一の方法は、データを示すことです。ここにa.csvb.csvがあります。BをAにマージしようとしています。

B には 3 つのフィールドがあり、A には 4 つのフィールドがあります。会社名 (ファイル A のみ)、ファンド名、資産クラス、および資産です。これまでのところ、私の焦点は、単語または文字列の一部を置き換えて完全に一致するものを作成し、次に使用することによってファンド名を一致させることでした。

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

ただし、これでは約 30% の一致しか得られません。残りは私が手作業で行う必要があります。

資産は数値フィールドであり、どちらも常に正しいとは限らず、ファンドの資産が少ない場合は大幅に変動する可能性があります。資産クラスは、両方のファイルで「一般的に」同じ文字列フィールドですが、相違点があります。

複雑さを増しているのは、ファイル B のさまざまな一連の資金です。たとえば、次のようになります。

AGF カナディアン バリュー

AGF カナディアン バリュー-D

この場合、シリーズ化されていないものを選ぶか、「A」「-A」「Advisor」などと呼ばれるものをマッチとして選ばなければなりません。

質問

最善のアプローチは何だと思いますか? この演習は毎月行う必要があり、手動で一致させるには非常に時間がかかります。コードの例は役に立ちます。

アイデア

私がうまくいくと思う方法の 1 つは、文字列内の各単語の最初の大文字に基づいて文字列を正規化することです。しかし、Rを使用してそれを実現する方法を理解できませんでした.

私が検討したもう 1 つの方法は、資産、ファンド名、資産クラス、および会社の組み合わせに基づいて一致のインデックスを作成することでした。しかし、繰り返しになりますが、Rでこれを行う方法がわかりません。または、それが可能かどうかさえわかりません。

コードの例、コメント、考え、方向性は大歓迎です!

4

4 に答える 4

9

1 つの簡単な提案: マージを使用する前に、さまざまなフィールドで個別にマッチングを行ってみてください。最も単純なアプローチはpmatch関数を使用することですが、R にはテキスト マッチング関数が不足していません (例: agrep)。簡単な例を次に示します。

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

データセットの場合、これは次のすべてのファンド名と一致します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

一致を作成したら、代わりにそれらを使用して簡単にマージできます。

于 2010-02-09T20:50:52.897 に答える
3

不正確な一致は分析全体を無効にするため、近似文字列一致はお勧めできません。各ソースからの名前が毎回同じである場合、インデックスを作成することも私にとって最良のオプションのようです。これはRで簡単に実行できます。

次のデータがあるとします。

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

おそらくpmatchなどを開始点として使用し、手動で検証して、各ソースの名前のインデックスを1回作成します。

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

次に、実行ごとに次を使用してマージします。

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

それは私たちに与えるでしょう:

  idx name.x price     name.y qty
1   1    Ace    10    Ace Co.   9
2   2  Bayes    13 Bayes Inc.  99
于 2010-02-10T04:13:38.187 に答える
0

私もカナダの地元の人です、ファンド名を認識してください。

各データプロバイダーが個々のファンド名に独自のフォームを選択するため、これは難しい問題です。ファンドまたはクラスのいずれかですべてが終わるように、異なる構造を使用するものもあれば、至る所にあるものもあります。それぞれが独自の短縮形も選択しているようで、これらは定期的に変更されます。

そのため、あなたのような多くの人々が定期的にこれを手作業で行っています。一部のコンサルティング会社は、さまざまなソースをリンクするためにインデックスを一覧表示していますが、そのルートを探索したかどうかはわかりませんか?

シェーンとマレクが指摘したように、これは単純な結合以上のマッチングタスクです。多くの企業がこれに苦労しています。私はこれについての私の仕事の真っ最中です...

ジェイ

于 2010-02-09T21:11:23.580 に答える