使用以下数据集,如何编写一个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)
答案 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" )