2017-11-21 25 views
2

複数のデータフレームを1つの「マスタ」データフレームにマージする複数のスレッドがありますが、代わりに1つの参照データフレームを取得し、他のデータフレームを分離したままにします。私はlapplyと 'for'ループを使用しようとしましたが、それを行う方法を理解していません。 (免責事項:私はR.に新たなんだ)1つのデータフレームを複数のデータフレームに個別にマージ/結合する

df_geoが基準データフレームであり、このようになります。

district sector cell village village_code 
west sectorA cellA villageA XXXXXXXX 
west sectorA cellA villageB XXXXXXXX 
west sectorB cellB villageC XXXXXXXX 
south sectorC cellC villageD XXXXXXXX 

のタイプに固有の情報をより多くの列を持っている他の三つのデータセットがあります。それに含まれるデータ、すなわち流通、調査、フォローアップ。すべてのデータセットには、地区、セクター、セル、および村(同じ名前)の列があります。例えば:

> df_distr 
v1 district sector cell village  v2 v3 … 
.. west sectorA cellA villageA .. .. … 
.. west sectorA cellA villageB .. .. … 
.. west sectorB cellB villageC .. .. … 
.. south sectorC cellC villageD .. .. … 

> df_survey 
v1 v5 v6 district sector cell village  v7 … 
.. .. .. west sectorA cellA villageA .. .. 
.. .. .. west sectorA cellA villageB .. .. 
.. .. .. west sectorB cellB villageC .. .. 
.. .. .. south sectorC cellC villageD .. .. 

各データフレームは、異なる数の列を有し、位置変数がそれぞれにおいて同じ数字列に含まれていません。各地区 - セクター - セル - 村の組み合わせは、各村のコードと同様にユニークです。地区セクターのセルビレッジの一致に基づいて8桁の数値のロケーションIDを記録する3つのデータフレームのそれぞれにvillage_code列を追加しようとしています。理想的には、(リストに保存されるのではなく)オリジナルの各データフレームに列を追加することをお勧めします。このように、私は彼らが次のようになりたいのですが:

> df_distr 
v1 district sector cell village  v2 v3 … village_code 
.. west sectorA cellA villageA .. .. … XXXXXXXX 
.. west sectorA cellA villageB .. .. … XXXXXXXX 
.. west sectorB cellB villageC .. .. … XXXXXXXX 
.. south sectorC cellC villageD .. .. … XXXXXXXX 

> df_survey 
v1 v5 v6 district sector cell village  v7 … village_code 
.. .. .. west sectorA cellA villageA .. .. XXXXXXXX 
.. .. .. west sectorA cellA villageB .. .. XXXXXXXX 
.. .. .. west sectorB cellB villageC .. .. XXXXXXXX 
.. .. .. south sectorC cellC villageD .. .. XXXXXXXX 

私が正常なdf_distr <- left_join(df_distr, df_geo, by = c("district", "sector", "cell", "village"))、この一つ一つ使用してコードを行うことができますが、私はより効率的に行う方法をしたいと思います。

+0

私が正しく理解していれば、あなたはそれらのすべては 'village_code'を持っているように、参照データセットと結合すべてのデータセットを残したいです添付された? – useR

+0

@useRはい、そうです – ktf

答えて

0

df_distrdf_surveylapplyの結果として、プリントアウトされることを

library(data.table) 

setDT(df_geo) 
setDT(df_distr) 
setDT(df_survey) 

lapply(list(df_distr, df_survey), 
     function(x) x[df_geo, village_code := i.village_code, 
        on=.(district, sector, cell, village)]) 

は注意してください、しかし、 data.frames自体が正常に修正されました。データを変更する際に何のコピーが存在しないため、この方法はまた、再割り当てするよりもはるかに高速であることを

library(purrr) 
walk(list(df_distr, df_survey), ~ .[df_geo, village_code := i.village_code, 
            on=.(district, sector, cell, village)]) 

注:あなたが唯一の:=の副作用をしたい場合は、lapply/mapように動作しますが、出力を抑制しpurrr::walkを、使用することができます。フレームは適所にある。

結果:

> df_distr 
    v1 district sector cell village v2 v3 village_code 
1: ..  west sectorA cellA villageA .. ..  XXXXXXXX 
2: ..  west sectorA cellA villageB .. ..  XXXXXXXX 
3: ..  west sectorB cellB villageC .. ..  XXXXXXXX 
4: .. south sectorC cellC villageD .. ..  XXXXXXXX 

> df_survey 
    v1 v5 v6 district sector cell village v7 village_code 
1: .. .. ..  west sectorA cellA villageA ..  XXXXXXXX 
2: .. .. ..  west sectorA cellA villageB ..  XXXXXXXX 
3: .. .. ..  west sectorB cellB villageC ..  XXXXXXXX 
4: .. .. .. south sectorC cellC villageD ..  XXXXXXXX 

データ:

df_geo = read.table(text = "district sector cell village village_code 
west sectorA cellA villageA XXXXXXXX 
        west sectorA cellA villageB XXXXXXXX 
        west sectorB cellB villageC XXXXXXXX 
        south sectorC cellC villageD XXXXXXXX", header = TRUE) 

df_distr = read.table(text = "v1 district sector cell village  v2 v3 
.. west sectorA cellA villageA .. .. 
.. west sectorA cellA villageB .. .. 
.. west sectorB cellB villageC .. .. 
.. south sectorC cellC villageD .. ..", header = TRUE) 


df_survey = read.table(text = "v1 v5 v6 district sector cell village  v7 
.. .. .. west sectorA cellA villageA .. 
.. .. .. west sectorA cellA villageB .. 
.. .. .. west sectorB cellB villageC .. 
.. .. .. south sectorC cellC villageD ..", header = TRUE) 
-1

私は4つのデータフレームのグループを持っているとしましょう。 referenceはdf_geo用のスタンドで、tab*データフレームは作業中の未知のテーブルを表します。

reference = data.frame(key = letters[1:10],value = 1:10) 
tab1 = data.frame(journey = LETTERS[1:3],key=letters[1:3]) 
tab2 = data.frame(trip = LETTERS[7:10],key=letters[7:10]) 
tab3 = data.frame(destination = LETTERS[4:8],key=letters[4:8]) 

目的は、referenceを他のデータフレームに結合することです。ここで

output = lapply(list(tab1=tab1,tab2=tab2,tab3=tab3),left_join,reference,by="key") 

私はtab*データフレームの(重要な)という名前のリストを作成して、それらのそれぞれに、この場合のleft_joinを同じ関数を適用するlapplyを使用しています。関数を指定したら、関数に他の必要な引数を渡すことができます。この場合は、結合するテーブル(reference)と結合する方法を示すby="key"です。

これはデータフレームのリストを返しますが、グローバル環境に戻したいと思うようです。

lapply(names(output),function(x){ 
    assign(x,value=output[[x]],envir=globalenv()) 
}) 

我々はlapplyを使用今回、我々は前のステップで割り当てられた名前である出力の名前(にそれを行う。我々assign名に地球環境にその名前を持つoutputの値。

ここで、すべてのデータフレームが更新されました。更新が必要なデータフレームの名前付きリストを作成するだけでした。あなたがデータフレームを再割り当てすることなく、village_code列を添付し、参照プロパティで変更data.table年代の利点を取ることができ