如何在r data.tables中[join on][where]

如何在r data.tables中[join on][where],r,data.table,R,Data.table,是否有一种方法可以组合data.table中的连接和子集功能?假设我有下表: dt = data.table(itemID = c(1,1,2,2),bucketID = c(1,2,2,3),value = 1:4) 我想将每个项目的最低存储桶的值设置为零。我的想法是跑步: ends = dt[,.(min = min(bucketID)),itemID] dt[ends,on="itemID",bucketID==min,value:=0] i、 e.连接表,找到两行相同的位置,然后更新

是否有一种方法可以组合data.table中的连接和子集功能?假设我有下表:

dt = data.table(itemID = c(1,1,2,2),bucketID = c(1,2,2,3),value = 1:4)
我想将每个项目的最低存储桶的值设置为零。我的想法是跑步:

ends = dt[,.(min = min(bucketID)),itemID]
dt[ends,on="itemID",bucketID==min,value:=0]
i、 e.连接表,找到两行相同的位置,然后更新值列。但这不起作用。我可以通过以下方法获得正确的结果:

ends = dt[,.(min = min(bucketID)),itemID]
dt = dt[ends,on="itemID"][bucketID==min,value:=0][,c(-4)]

然而,这似乎有点迂回。有没有更好的方法来组合join和where?

扩展您的join方法,您可以通过
itemID
min
值来加入

dt[
    ends
    , on = c("itemID", bucketID = "min")
    , value := 0
]

dt
#    itemID bucketID value
# 1:      1        1     0
# 2:      1        2     2
# 3:      2        2     0
# 4:      2        3     4

可能是
dt[ends,on=c(“itemID”,bucketID=“min”),value:=0]
?或者可能完全避免连接-
dt[dt[,bucketID==min(bucketID),by=itemID]$V1,value:=0]
@LateMail将是一个关于更大数据的有趣基准。从上面对
dt2@LateMail的快速测试中,加入似乎比我的建议快了一点-这是否包括
结束
步骤?我得到了不同的结果
system.time(dt2[dt2[,(min=min(bucketID)),itemID],on=c(“itemID”,bucketID=“min”),value:=0])
vs
system.time(dt2[dt2[,bucketID==min(bucketID),by=itemID]$V1,value:=0)
显示连接的速度似乎快了4-5倍。@Late Mail-有趣的是:我使用的是
dt3如果顺序是在开始时设置的
setorder(dt3,itemID,bucketID)
,那么我的方法会更快,但是如果是随机的,你的方法会更快