使用data.table包通过引用进行条件二进制连接和更新

Dav*_*urg 8 join r data.table

所以这是我现实生活中的问题,我觉得这个问题很容易解决,我在这里遗漏了一些明显的东西.我有两个叫做TK和的大数据集DFT

library(data.table)
set.seed(123)
(TK <- data.table(venue_id = rep(1:3, each = 2), 
                  DFT_id = rep(1:3, 2), 
                  New_id = sample(1e4, 6),
                  key = "DFT_id"))

#    venue_id DFT_id New_id
# 1:        1      1   2876
# 2:        1      2   7883
# 3:        2      3   4089
# 4:        2      1   8828
# 5:        3      2   9401
# 6:        3      3    456

(DFT <- data.table(venue_id = rep(1:2, each = 2), 
                   DFT_id = 1:4, 
                   New_id = sample(4),
                   key = "DFT_id"))

#    venue_id DFT_id New_id
# 1:        1      1      3
# 2:        1      2      4
# 3:        2      3      2
# 4:        2      4      1
Run Code Online (Sandbox Code Playgroud)

我想执行一个二进制左连接TKDFT_id列时venue_id %in% 1:2,在更新New_id 的参考.换句话说,期望的结果将是

TK
#    venue_id DFT_id New_id
# 1:        1      1      3
# 2:        2      1      3
# 3:        1      2      4
# 4:        3      2   9401
# 5:        2      3      2
# 6:        3      3    456
Run Code Online (Sandbox Code Playgroud)

我想要结合这两个条件,但它不起作用(仍然不确定为什么)

TK[venue_id %in% 1:2 & DFT, New_id := i.New_id][]
# Error in `[.data.table`(TK, DFT & venue_id %in% 1:2, `:=`(New_id, i.New_id)) : 
#   i is invalid type (matrix). Perhaps in future a 2 column matrix could return a list of elements of DT (in the spirit of A[B] in FAQ 2.14). 
# Please let datatable-help know if you'd like this, or add your comments to FR #1611.
Run Code Online (Sandbox Code Playgroud)

我的下一个想法是使用链接部分实现目标,通过正确连接,但在一些临时表上,而不实际影响 TK

TK[venue_id %in% 1:2][DFT, New_id := i.New_id][]
TK
#    venue_id DFT_id New_id
# 1:        1      1   2876
# 2:        2      1   8828
# 3:        1      2   7883
# 4:        3      2   9401
# 5:        2      3   4089
# 6:        3      3    456
Run Code Online (Sandbox Code Playgroud)

所以说清楚,我很清楚我可以分成TK两个表,执行连接然后rbind再次,但我正在做这样的许多不同的条件连接,我也在寻找速度和内存有效的解决方案.

这也意味着我不是在寻找dplyr解决方案,因为我正在尝试使用二进制连接和仅通过data.table IIRC包中存在的引用功能进行更新.


有关其他信息,请参阅以下小插图:

Dav*_*rek 8

从Arun的更新答案复制到这里

TK[venue_id %in% 1:2, New_id := DFT[.SD, New_id]][]
#    venue_id DFT_id New_id
# 1:        1      1      3
# 2:        2      1      3
# 3:        1      2      4
# 4:        3      2   9401
# 5:        2      3      2
# 6:        3      3    456
Run Code Online (Sandbox Code Playgroud)

他的答案给出了正在发生的事情的细节.


edd*_*ddi 5

这是一个非常简单的方法:

TK[DFT, New_id := ifelse(venue_id %in% 1:2, i.New_id, New_id)][]
#    venue_id DFT_id New_id
# 1:        1      1      3
# 2:        2      1      3
# 3:        1      2      4
# 4:        3      2   9401
# 5:        2      3      2
# 6:        3      3    456
Run Code Online (Sandbox Code Playgroud)

我没有检查,但我怀疑其他答案更快.

  • @Arun我同意.虽然这两种解决方案对我来说都不是特别美观,但我几乎都希望OP的原始尝试工作,除非它没有任何意义. (2认同)