【问题标题】:Subsetting a data.table using another data.table使用另一个 data.table 子集 data.table
【发布时间】:2014-01-08 06:21:50
【问题描述】:

我有 dtdt1 data.tables。

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% 适用于向量而不适用于多列对象。尽管如此,我无法找到更有效的方法来做到这一点......

提前感谢您的帮助!

【问题讨论】:

    标签: r data.table subset


    【解决方案1】:
    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
    

    【讨论】:

    • 非常感谢!可能这个在非常大的data.tables 中更快。
    • 如果您不想要performance 列,那么执行dt[dt1, list(event), nomatch=0L] 应该会快一点...
    • data.table 提供了自己的merge 方法,该方法按照这些方式工作。我希望速度会相似。
    • ?merge 已经提到X[Y ...]merge 快,但它并没有那么慢(尤其是对于这个问题中的任务)。
    • @Riccardo,不,只要您不使用:=,就不会发生引用更新。您可以自己尝试一下。执行ans &lt;- dt[dt1, list(event), nomatch=0L] 并检查ansdtdt1
    【解决方案2】:

    使用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
    

    【讨论】:

    • OMG,有时解决方案很简单,以至于您看不到它...谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-25
    • 2015-07-14
    • 2013-12-15
    • 2013-01-08
    • 2015-12-24
    相关资源
    最近更新 更多