2014-04-29 144 views
2

我遇到以下情況。甲data.table看起來如下R擴展出data.table

x = data.table(
id1 = c('a','b','c'), 
id2 = c('x','y','x'), 
val = c(0.2,0.3,0.5)) 

我有兩個其他數據表,給的值之間的映射在id1id2看起來像下面

id1.dt = data.table(
id1 = c('a','a','a','b','b','c'), 
fid = c('1232','3224','3434','234','231','332') 
) 

id2.dt = data.table(
id2 = c('x','x','y','y'), 
fid = c('334','443','344','24') 
) 

我希望能夠做的是通過保留values co擴大上述data.table x這樣我就可以得到一個完整的交叉連接,但是通過使用fid列。因此,預期的最終表

id1 id2 val 
1232 334 0.2 
1232 443 0.2 
3224 334 0.2 
3224 443 0.2 
3434 334 0.2 
3434 443 0.2 
... 

基本上,在x我想利用id1id2所有FID值與其他兩個表,並保留val值的每一行。我嘗試過使用CJ,但沒有達到目標。任何幫助讚賞。

回答

6

有點彆扭,但這應該這樣做:

setkey(x, id1) 
(setkey(x[id1.dt], id2))[ 
    id2.dt, allow.cartesian=T][ 
    order(val), -(1:2), with=FALSE 
] 

產地:

val fid fid.1 
1: 0.2 1232 334 
2: 0.2 3224 334 
3: 0.2 3434 334 
4: 0.2 1232 443 
5: 0.2 3224 443 
6: 0.2 3434 443 
7: 0.3 234 344 
8: 0.3 231 344 
9: 0.3 234 24 
10: 0.3 231 24 
11: 0.5 332 334 
12: 0.5 332 443 

您也可以嘗試merge.data.table實現了類似的結果在一定程度上更直觀地抓握的形式:

merge(
    merge(x, id1.dt, by="id1"), 
    id2.dt, by="id2", allow.cartesian=T 
)[, -(1:2), with=F] 
+0

我喜歡這兩種解決方案,但特別是這種合併(合併(尼斯! –