2014-04-29 106 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

我喜欢这两种解决方案,但特别是这种合并(合并(尼斯! –