2013-08-20 69 views
2

合併類似的情況我有兩個數據幀(實際data.tables)。與兩個data.tables

set.seed(123) 
dt1 <- data.table(P=rep(letters[1:3],c(4,2,3)),X=sample(9)) 
dt1 
    P X 
1: a 3 
2: a 7 
3: a 9 
4: a 6 
5: b 5 
6: b 1 
7: c 2 
8: c 8 
9: c 4 

和:

dt2 <- data.table(P=rep(letters[1:5],length=10),D=c("X","Y","Z","G","F")) 
dt2 
    P D 
1: a X 
2: b Y 
3: c Z 
4: d G 
5: e F 
6: a X 
7: b Y 
8: c Z 
9: d G 
10: e F 

現在我想添加一個新列DT1,DT2與列 「d」,其中P在DT1及DT2的值相同。它應該是這樣的:

dt_new 
    P X D 
1: a 3 X 
2: a 7 X 
3: a 9 X 
4: a 6 X 
5: b 5 Y 
6: b 1 Y 
7: c 2 Z 
8: c 8 Z 
9: c 4 Z 
+0

請修正你的語法,因此您的代碼可以運行。 – Frank

+0

對不起,代碼固定! – beginneR

回答

5

我會以這種方式做一個data.table join

setkey(dt1, P) 
dt1[unique(dt2),nomatch=0] 

    P X D 
1: a 3 X 
2: a 7 X 
3: a 9 X 
4: a 6 X 
5: b 5 Y 
6: b 1 Y 
7: c 2 Z 
8: c 8 Z 
9: c 4 Z 
+0

這很好,謝謝! – beginneR

4

+1到阿倫的回答。要顯示更新按引用的方式來做到這一點......從問題

示例數據再次:

set.seed(123) 
dt1 = data.table(P=rep(letters[1:3],c(4,2,3)),X=sample(9)) 
dt2 = data.table(P=rep(letters[1:5],length=10),D=c("X","Y","Z","G","F")) 

在例如數據刪除的DUP使用unique()爲阿倫做的:

dt2 = unique(dt2) 
dt2 
    P D 
1: a X 
2: b Y 
3: c Z 
4: d G 
5: e F 

現在通過參考dt1與來自dt2的數據相加。像SQL中的外鍵一樣。誠然,這種語法並不明顯或者特別優雅,但它確實避免了dt1的副本。因此,如果dt1的大小是10GB,則速度可能會更快。

setkey(dt2, P) 
dt1[,D:={ .P=P   # allows us to refer to the P from dt1 on next line 
      dt2[.P,D]$D}] # since P is type character, no need to J() or .() 
dt1 
    P X D 
1: a 3 X 
2: a 7 X 
3: a 9 X 
4: a 6 X 
5: b 5 Y 
6: b 1 Y 
7: c 2 Z 
8: c 8 Z 
9: c 4 Z 

或者,保持在DT2的重複:

set.seed(123) 
dt1 = data.table(P=rep(letters[1:3],c(4,2,3)),X=sample(9)) 
dt2 = data.table(P=rep(letters[1:5],length=10),D=c("X","Y","Z","G","F")) 
setkey(dt2,P) 
dt2 
    P D 
1: a X 
2: a X 
3: b Y 
4: b Y 
5: c Z 
6: c Z 
7: d G 
8: d G 
9: e F 
10: e F 
dt1[,D:={ .P=P 
      dt2[.P,D,mult="first"]}] 
dt1 
    P X D 
1: a 3 X 
2: a 7 X 
3: a 9 X 
4: a 6 X 
5: b 5 Y 
6: b 1 Y 
7: c 2 Z 
8: c 8 Z 
9: c 4 Z 
+0

我想你的意思是除了連接列之外''dt1'的額外列不會以這種方式複製?我對你有正確的理解嗎? – eddi

+0

@eddi是,沒有'dt1'列被複制,連接列或其他。 Arun的答案返回一個新的data.table。另一種自然的參考方式是'dt1 [dt2,D:= i.D]',但我似乎記得我們不能在':='的右側使用'i''符號。這種方式需要'dt1'(典型的大表)被鍵入,而不是'dt2'(典型的小查找表)。但另一方面,一旦'dt1'被鍵入,從'dt2'加入的行就會少得多,所以速度會更快。 –

+0

謝謝。不幸的是,我不知道發生了什麼...... – beginneR