使用 data.table 包通过引用进行条件二进制连接和更新
Conditional binary join and update by reference using the data.table package
所以这是我现实生活中的问题,我觉得它很容易解决,但我在这里遗漏了一些明显的东西。我有两个大数据集 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
我想在 venue_id %in% 1:2
时在 DFT_id
列上执行 二进制左连接 到 TK
,同时更新 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
我想把这两个条件结合起来,但没有成功(仍然不确定为什么)
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.
我的下一个想法是使用链接,它通过正确连接部分实现了目标,但在一些临时 table 上没有实际影响 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
所以要明确一点,我很清楚我可以将 TK
分成两个 table,执行连接然后再次 rbind
,但我正在做许多不同的条件连接都是这样的,我也在寻找速度和内存高效的解决方案。
这也意味着我 不是 寻找 dplyr
解决方案,因为我正在尝试同时使用 binary join 和 通过引用更新 仅存在于 data.table
软件包 IIRC 中的功能。
有关更多信息,请参阅这些小插图:
从 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
他的回答给出了正在发生的事情的详细信息。
这是一个非常简单的方法:
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
我没有检查过,但我怀疑其他答案更快。
所以这是我现实生活中的问题,我觉得它很容易解决,但我在这里遗漏了一些明显的东西。我有两个大数据集 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
我想在 venue_id %in% 1:2
时在 DFT_id
列上执行 二进制左连接 到 TK
,同时更新 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
我想把这两个条件结合起来,但没有成功(仍然不确定为什么)
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.
我的下一个想法是使用链接,它通过正确连接部分实现了目标,但在一些临时 table 上没有实际影响 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
所以要明确一点,我很清楚我可以将 TK
分成两个 table,执行连接然后再次 rbind
,但我正在做许多不同的条件连接都是这样的,我也在寻找速度和内存高效的解决方案。
这也意味着我 不是 寻找 dplyr
解决方案,因为我正在尝试同时使用 binary join 和 通过引用更新 仅存在于 data.table
软件包 IIRC 中的功能。
有关更多信息,请参阅这些小插图:
从 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
他的回答给出了正在发生的事情的详细信息。
这是一个非常简单的方法:
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
我没有检查过,但我怀疑其他答案更快。