2013-12-19 52 views
3

我有dtdt1data.table s。使用另一个data.table来设置data.table

dt<-data.table(id=c(rep(2, 3), rep(4, 2)), year=c(2005:2007, 2005:2006), event=c(1,0,0,0,1)) 
dt1<-data.table(id=rep(2, 5), year=c(2005:2009), performance=(1000:1004)) 

dt 

    id year event 
1: 2 2005  1 
2: 2 2006  0 
3: 2 2007  0 
4: 4 2005  0 
5: 4 2006  1 

dt1 

    id year performance 
1: 2 2005  1000 
2: 2 2006  1001 
3: 2 2007  1002 
4: 2 2008  1003 
5: 2 2009  1004 

我想使用也出现在dt1其第一和第二列的组合,子集前者。由于这个原因,我想创建一个新对象而不会覆盖dt。这是我想要获得的。

id year event 
1: 2 2005  1 
2: 2 2006  0 
3: 2 2007  0 

我试图做到这一点使用下面的代码:

dt.sub<-dt[dt[,c(1:2)] %in% dt1[,c(1:2)],] 

,但没有奏效。结果,我收回了一张与dt相同的数据表。我认为我的代码中至少有两个错误。首先,我可能使用错误的方法按列排序data.table。第二种,很明显,%in%适用于向量,而不适用于多列对象。无论如何,我无法找到一个更有效的方式来做到这一点...

在此先感谢您的帮助!

回答

8
setkeyv(dt,c('id','year')) 
setkeyv(dt1,c('id','year')) 
dt[dt1,nomatch=0] 

输出 -

> dt[dt1,nomatch=0] 
    id year event performance 
1: 2 2005  1  1000 
2: 2 2006  0  1001 
3: 2 2007  0  1002 
+0

非常感谢!很可能这个在更大的data.table中速度更快。 – Riccardo

+1

如果你不想'performance'列,那么'dt [dt1,list(event),nomatch = 0L]'应该稍微快一点...... – Arun

+0

'data.table'提供自己的'merge'方法,它沿着这些方向工作。我希望速度是相似的。 – James

4

使用merge

merge(dt,dt1, by=c("year","id")) 
    year id event performance 
1: 2005 2  1  1000 
2: 2006 2  0  1001 
3: 2007 2  0  1002 
+0

OMG,有时它是那么容易,你不能看到它...谢谢 的解决方案! – Riccardo