R data.table在多个条件下的子集。

时间:2013-11-20 03:45:07

标签: r data.table

使用以下数据集,如何编写一个data.table调用,该子集对此表进行子集并返回该客户的所有客户ID和相关订单,如果客户购买了SKU 1?

预期结果应该返回一个表格,该表格在该条件下排除cid 3和5以及与sku == 1匹配的客户的每一行。

我因为不知道怎么写“包含”语句而陷入困境,== literal只返回sku的匹配条件......我相信还有更好的方法..

library("data.table")    
df<-data.frame(cid=c(1,1,1,1,1,2,2,2,2,2,3,4,5,5,6,6),
    order=c(1,1,1,2,3,4,4,4,5,5,6,7,8,8,9,9),
    sku=c(1,2,3,2,3,1,2,3,1,3,2,1,2,3,1,2))

    dt=as.data.table(df)

2 个答案:

答案 0 :(得分:9)

这与previous answer类似,但此处子集的工作方式更为data.table

首先,让我们采取符合我们条件的cid:

matching_cids = dt[sku==1, cid]

%in%运算符允许我们过滤到列表中包含的那些项目。所以,使用上面的内容:

dt[cid %in% matching_cids]

或在一行:

> dt[cid %in% dt[sku==1, cid]]
     cid order sku
  1:   1     1   1
  2:   1     1   2
  3:   1     1   3
  4:   1     2   2
  5:   1     3   3
  6:   2     4   1
  7:   2     4   2
  8:   2     4   3
  9:   2     5   1
 10:   2     5   3
 11:   4     7   1
 12:   6     9   1
 13:   6     9   2

答案 1 :(得分:3)

我原以为 more (?!)data.table使用keys。我无法弄清楚如何将所有内容放在一行上,但我认为这对大数据来说会更快一些,因为我理解它(我可能很错误)这是目前为止唯一能避免矢量扫描的解决方案(与二分搜索相比速度慢):

#  Set initial key
setkey(dt,sku)

#  Select only rows with 1 in the sku and return first example of each, setting key to customer id
dts <- dt[ J(1) , .SD[1] , keyby = cid ]

#  change key of dt to cid to match customer id
setkey(dt,cid)

#  join based on common key
dt[dts,.SD]
#    cid order sku
# 1:   1     1   1
# 2:   1     1   2
# 3:   1     2   2
# 4:   1     1   3
# 5:   1     3   3
# 6:   2     4   1
# 7:   2     5   1
# 8:   2     4   2
# 9:   2     4   3
#10:   2     5   3
#11:   4     7   1
#12:   6     9   1
#13:   6     9   2

您可以在一行中执行的替代方法是使用data.table merge,如此...

setkey(dt,sku)
merge( dt[ J(1) , .SD[1] , keyby = cid ] , dt , by = "cid" )