2016-08-27 3 views
-2

私はUbuntu 16.04を持っていて、Rをターミナルで実行します。 私は大きなデータテーブルを扱っています.175万行と11列(dt1)、もう1つは700万行と7列(dt2)です。すべての値は数値です。両方のテーブルに 'id'カラムがあります。私は、2番目のものの5つの列として5列の同じ値を持つ最初の行のすべての行を見つけ、これらの行の最初のデータテーブル 'id'値を2番目のデータテーブルのものに変更する必要があります。どちらのデータ表でも、比較された列の名前は同じですが、それらがV1、V2、V3、V4およびV5であるとします。私は2番目のデータテーブルをデータフレームフォーマットに変換したので、インデックスとして 'id'を使用できます。私は最初の行を1000回試してみたところ、40分かかりました。他の列の値を変更するために5列のデータを一致させるテーブル

for (i in 1:1000) { 
    dt1[(V1==dt2[i,V1] & V2==dt2[i,V2] & 
     V3==dt2[i,V3] & V4==dt2[i,V4] & 
     V5==dt2[i,V5]), id:=i] 
} 

私はそれを並列化しようとしていますが、メモリが狭くなっているため、2つまたは3つのコアしか使用できません。明らかに、それは十分ではありません。私の家のコンプでそれを行うための迅速かつ効率的な方法はありますか? AWSでそれを行うには、どんなトリックが役に立つのでしょうか?特に、同時にいくつのコアを使用できますか?

答えて

4

Rでは、可能な限りループを回避することが常に推奨されます。通常は、代替ベクトル化ソリューションよりもはるかに遅いためです。

この操作は、data.table結合を使用して行うことができます。基本的には、実行するとき

dt1[dt2]; 

2つのデータテーブルの間で右結合を実行しています。プリセットキー列dt1は、どの列に結合するかを決定します。 dt1にプリセットキーがない場合、操作は失敗します。しかし、あなたは手動オンザフライキー列を選択するために、on引数を指定することができます。

key <- paste0('V',1:5); 
dt1[dt2,on=key]; 

(もちろんの代替がsetkey()またはsetkeyv()のいずれかを使用してキーを、あらかじめ設定してある。)

上記操作は実際にはdt1dt2の両方からのデータを含むマージされたテーブルを返します。これはあなたが望むものではありません。しかし、idの列をidの列にに割り当てるには、のdata.tableインデックス関数のj引数と:=のインプレースアサイン構文を使用できます。名前の競合があるため、idの列をdt2に参照する場合はi.idを使用し、idの場合はidの列を引き続き参照してdt1を参照する必要があります。これは単に競合する名前をあいまいにするためにdata.tableによって提供されるメカニズムです。したがって、あなたが探している:

dt1[dt2,on=key,id:=i.id]; 

ここでは2つだけのキー列と(簡単にするために)データのほんの数行を使用する例です。一致しない行には、操作に影響されないIDが残っていることを示すために、不一致の行がいくつか含まれるようにキーを生成しました。

set.seed(1L); 
dt1 <- data.table(id=1:12,expand.grid(V1=1:3,V2=1:4),blah1=rnorm(12L)); 
dt2 <- data.table(id=13:18,expand.grid(V1=1:2,V2=1:3),blah2=rnorm(6L)); 
dt1; 
##  id V1 V2  blah1 
## 1: 1 1 1 -0.6264538 
## 2: 2 2 1 0.1836433 
## 3: 3 3 1 -0.8356286 
## 4: 4 1 2 1.5952808 
## 5: 5 2 2 0.3295078 
## 6: 6 3 2 -0.8204684 
## 7: 7 1 3 0.4874291 
## 8: 8 2 3 0.7383247 
## 9: 9 3 3 0.5757814 
## 10: 10 1 4 -0.3053884 
## 11: 11 2 4 1.5117812 
## 12: 12 3 4 0.3898432 
dt2; 
## id V1 V2  blah2 
## 1: 13 1 1 -0.62124058 
## 2: 14 2 1 -2.21469989 
## 3: 15 1 2 1.12493092 
## 4: 16 2 2 -0.04493361 
## 5: 17 1 3 -0.01619026 
## 6: 18 2 3 0.94383621 
key <- paste0('V',1:2); 
dt1[dt2,on=key,id:=i.id]; 
dt1; 
##  id V1 V2  blah1 
## 1: 13 1 1 -0.6264538 
## 2: 14 2 1 0.1836433 
## 3: 3 3 1 -0.8356286 
## 4: 15 1 2 1.5952808 
## 5: 16 2 2 0.3295078 
## 6: 6 3 2 -0.8204684 
## 7: 17 1 3 0.4874291 
## 8: 18 2 3 0.7383247 
## 9: 9 3 3 0.5757814 
## 10: 10 1 4 -0.3053884 
## 11: 11 2 4 1.5117812 
## 12: 12 3 4 0.3898432 
+0

迅速で詳細な返信に感謝します。いくつかの不一致があり、2番目のテーブルからのすべての試合についてのみ気にするなら、all.y = Tを使うべきです、そうですか?そしてすべてのミスマッチはNAとしてマークされますか? – Mathemilda

+0

こんにちは@Mathemilda。私たちはdata.tableの機能に穴を見つけたようです。 'dt1 [dt2]'インデックス結合構文を使用して左結合を達成する方法が見つけられません。これは、ここで必要なものです。 'merge.data.table()'関数は、 'all。y 'パラメータを指定するが、割り当てを指定するための 'j'パラメータをサポートしていないので、それを使用することはできません。インデックス付け関数の 'nomatch'パラメータは、右結合(デフォルトである' nomatch = NA')から内部結合( 'nomatch = 0')への変更のみをサポートします。同じインデックス結合割り当てで、不一致をNAに置き換える方法はありません。 – bgoldst

+0

回避策は、index-join-assignment操作を実行する 'id'カラム* prior *全体を効果的に無効にし、' dt2'から一致する行だけを設定することです。残りはNAとして残される。 IOW、index-join-assignmentを実行する前に 'dt1 $ id < - NA;'を実行してください。 – bgoldst

関連する問題