如何检查一列中的每一行是否落在其他两列的范围之间?

时间:2018-06-22 02:00:37

标签: r data.table

我有两个数据表,每个数据表包含> 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)

我希望会有一个使用数据表的更优化的解决方案。非常感谢所有建议。非常感谢。

1 个答案:

答案 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',但除非将其转换为字符列,否则您不能对数字列执行此操作。