2017-02-10 8 views
2

私は2つの大きなデータセットd1d2を持っています。これは、一意の変数idAとのマッチに基づいてマージしたいと思います。1つの変数に一致する2つのデータセットを効率的にマージするOR

両方とも両方のデータセットに存在しますが、どちらもエラーと欠損値(NAs)を含む場合があり、idAidBが別のデータセットの異なる観測点を指しています。例は以下の通りです。

希望する結果は以下のとおりです。基本的に、一致はidAまたはidBのいずれかにあります。重複した一致の場合は、idAの一致がidBと一致するように設定する必要があります。

実際のデータセットはかなり大きく(10億円)です。

Rでこれを実装する方法はありますか?

また、このようなSQLの結合の技術用語はありますか?

library(tidyverse) 
library(data.table) 

d1 <- read.table(text= 
"idA idB value1 
A 10 500 
B 1 111 
C 4 234 
D NA 400 
E 7 500 
NA 3 700 
Z 5 543 
Q 9 567 
U 23 723 
", 
header=T) %>% data.table 


d2 <- read.table(text= 
"idA idB value2 
A 10 11 
B 1 12 
L 21 15 
D 15 12 
E 8 17 
M 3 18 
N 5 13 
Z 25 17 
Q 23 12 
", 
header=T) %>% data.table 

所望の結果である:

Out <- read.table(text= 
"d1.idA d2.idA d1.idB d2.idB d1.v1 d2.v2 
A A 10 10 500 11 # matched on idA and idB 
B B 1 1 111 12 # matched on idA and idB 
D D NA 15 400 12 # matched on idA. d2.idB had NAs 
E E 7 8 500 17 # matched on idA. idB had divergent values 
NA M 3 3 700 18 # matched on idB. d1.idA had NAs 
Z Z 5 25 543 13 # d1[7,] matched to d2[8,] on idA and d2[9,] on idB. Priority given to idA match. 
Q Q 9 23 657 17 # d2[9,] matched to d1[8,] on idA and d1[9,] on idB. Priority given to idA match. 
", 
header=T) %>% data.table 

#Non matched rows 
# d1[3,] 
# d2[3,] 

EDIT1:

  • は、所望の結果
  • を加えは、読者による 解析の容易さ(read.tableを)data.table維持実際のデータはfread(ファイル)からのものです。

EDIT2:希望の結果から一致しない行を削除します。

+1

@akrun、私はこれがどのように重複しているのか分かりません。私はどのように2つのid変数で結合するかについて尋ねています。 (疑問は、同じ変数の内、左、剛性の結合を指します) – LucasMation

+0

ロビー活動を再開する前に、希望する結果をあなたの例に記入してください。 "idB以上のidA一致に優先する必要があります"ということは、それ自身ではっきりしていません。また、fyiの場合、データセットが大きい場合は、data.table(read.table(。))の代わりに 'fread'を使用することをお勧めします。これは、読み込みが遅くなり、読み込みが遅くなり、 DTに変換します。 – Frank

+0

は要求された機能を追加しました。それでも元の質問は、重複して表示された質問に完全に無関係です – LucasMation

答えて

1

希望の結果を得るためのエレガントな方法がわかりません(また、このタイプのSQLの操作に関する技術用語もわかりません)。

したがって、私は4つのステップでこれを達成するために示唆している:

  1. インナー、idAidB上の2つdata.tablesを結合data.tablesの各々に残りの行を決定します。
  2. 2つのデータテーブルの残りの行をidAに結合し、残りの行を再度決定します。
  3. 2つのデータテーブルの残りの行をidBに結合します。
  4. 前の手順の結果を結合します。すべての4つのステップのために

コード:。、

m1m2

# match_on idA idB value1 idx idA idB value2 idx 
#1:  AB A 10 500 1 A 10  11 1 
#2:  AB B 1 111 2 B 1  12 2 
#3:  A. D NA 400 4 D 15  12 4 
#4:  A. E 7 500 5 E 8  17 5 
#5:  A. Z 5 543 7 Z 25  17 8 
#6:  A. Q 9 567 8 Q 23  12 9 
#7:  .B NA 3 700 6 M 3  18 6 
d1d2の行の行IDを覚えておくために使用されるRESPをもたらす

library(data.table) 

# create index column in both data.tables 
d1[, idx := .I] 
d2[, idx := .I] 

# inner join on idA and idB 
j1 <- d1[d2, .(idx, i.idx), on = c("idA", "idB"), nomatch = 0L] 
m1 <- unique(j1$idx) 
m2 <- unique(j1$i.idx) 

# inner join on idA 
j2 <- d1[!(idx %in% m1)][d2[!(idx %in% m2)], .(idx, i.idx), on = c("idA"), nomatch = 0L] 
m1 <- append(m1, unique(j2$idx)) 
m2 <- append(m2, unique(j2$i.idx)) 

# inner join on idB 
j3 <- d1[!(idx %in% m1)][d2[!(idx %in% m2)], .(idx, i.idx), on = c("idB"), nomatch = 0L] 
m1 <- append(m1, unique(j3$idx)) 
m2 <- append(m2, unique(j3$i.idx)) 

# combine results 
rbindlist(
    list(
    AB = cbind(
     d1[idx %in% j1[, idx]], 
     d2[idx %in% j1[, i.idx]]), 
    A. = cbind(
     d1[idx %in% j2[, idx]], 
     d2[idx %in% j2[, i.idx]]), 
    .B = cbind(
     d1[idx %in% j3[, idx]], 
     d2[idx %in% j3[, i.idx]])), 
    fill = TRUE, 
    idcol = "match_on") 

、以前の結合操作の1つですでに使用されています。

したがって、一致を見つけていないd1d2で最後に残りの行を印刷することができる:各動作に参加のみ行インデックスではなく、すべての列を保持する保持されること

d1[!(idx %in% m1)] 
# idA idB value1 idx 
#1: C 4 234 3 
#2: U 23 723 9 
d2[!(idx %in% m2)] 
# idA idB value2 idx 
#1: L 21  15 3 
#2: N 5  13 7 

注、 。異なる結合操作の結果は、列の名前と位置が異なります。

最後の結合ステップでは、元のデータテーブルd1およびd2の行が、これらのインデックスを使用して選択され、均一な見栄えの結果表が作成されます。

+0

美しい、tks! – LucasMation

+0

この質問は解決しましたか?その場合は、ティックマークをチェックして解像度を確認してください。 – Parfait

関連する問題