我有两个数据表,每个数据表包含> 50k行和> 150列。我想找到一种方法来遍历DT1中ID列中的每一行,以查看它是否位于DT2中其他两列的任何行之间或等于该行。
如果它确实介于两个之间,我想用DT2中的相应HighID创建一个列。如果不是,则返回“ False”。
为简单起见,我在下面创建了一个数据表示例:
library(data.table)
DT1 <- data.table(
CheckID = c(52702746325, 14179966429, 52127746410, 13151126534, 52274366388,
21501526375)
)
DT2 <- data.table(
LowID = c(14179966412, 52274366385, 52127746410, 52702746323),
HighID = c(14179966429, 52274366389, 52127746410, 52702746325)
)
我希望DT1的输出看起来像这样:
CheckID HighID
1: 52702746325 52702746325
2: 14179966429 14179966429
3: 52127746410 52127746410
4: 13151126534 False
5: 52274366388 52274366389
6: 21501526375 False
请注意,我有一个用于数据框的函数(如下),但是对于我的完整数据集,由于我在整个脚本中进行了多次迭代和多次检查,因此需要6个小时以上才能完成。
factor <- as.character(DT2$HighID)
f <- function(x){
a <- factor[ (DT2$LowID<= x) & (x <= DT2$HighID) ]
if (length(a) == 0) FALSE else max(subset(DT2$HighID, DT2$LowID <= x & DT2$HighID>= x))
DT1$HighID <- sapply(DT1$CheckID, f)
我希望会有一个使用数据表的更优化的解决方案。非常感谢所有建议。非常感谢。
答案 0 :(得分:4)
如评论中所述,这是常规的非平等参加。一种方法是:
DT1[DT2, HighID := i.HighID, on = .(CheckID >= LowID, CheckID <= HighID)]
# > DT1
# CheckID HighID
# 1: 52702746325 52702746325
# 2: 14179966429 14179966429
# 3: 52127746410 52127746410
# 4: 13151126534 NA
# 5: 52274366388 52274366389
# 6: 21501526375 NA
on = .(CheckID >= LowID, CheckID <= HighID)
指定连接条件,i.HighID
引用HighID
中的DT2
列。
您要在NA行中放置'False',但除非将其转换为字符列,否则您不能对数字列执行此操作。