检查数据框中的值是否有条件地位于另一个数据框的两列指定的值范围之间

Check if a value in a dataframe is conditionally between a range of values specified by two columns of another dataframe

所以,我有两个 dataframes - 有点大(df1 ~= 20k 行 & df2 ~= 150 万) - 我想检查 df1 中的值是否介于 df2$low & df2$high,但有条件地执行(以限制检查次数)并且仅在 abs(df1$val-df2$val) < 2 时才执行检查。如果发现 df1 中的值在 df2 范围内,则添加到具有 TRUE/FALSE 个值的新列中。

df1

weight low high
94.99610 94.99608 94.99613
95.00561 95.00558 95.00566

df2

index th_weight
1 94.996092
2 95.496336
3 95.509906
4 97.473292
5 100.519060

期望的输出应该是:

df1

weight lower upper filter
94.99610 94.99608 94.99613 TRUE
95.00561 95.00558 95.00566 FALSE

因此在该示例中,逻辑是 df2 中的第 4 行和第 5 行将被省略。 df2 的第 1 行中的值在 df1$low & df1$high 的第 1 行内,因此 df1[,filter := TRUE] 对于该权重

我尝试了多种方法,双循环进入 data.table,正如预期的那样,这是效率最低的,我还尝试用 [=21] 制作 df1 x df2 的笛卡尔积=] 但那里有内存问题。即使拆分成块并附加到文件中(这样我以后可以通过 UNIX sedawk 轻松操作文件)也没有帮助。

可能有一个非常简单的方法来做到这一点,我可能完全偏离了轨道,所以我提前道歉。

使用 non-equi 与 data.table 连接 - 将第一个数据转换为 data.table (setDT),创建 filter 列作为逻辑列 (FALSE) 值。执行 non-equi 连接,并将 filter 分配 (:=) 到 TRUE,这仅在条件 ( abs(weight - th_weight) < 2) 遇见

library(data.table)
setDT(df1)[, filter := FALSE]
df1[df2, filter := abs(weight - th_weight) < 2, 
       on = .(low <= th_weight, high >= th_weight)]

-输出

> df1
     weight      low     high filter
      <num>    <num>    <num> <lgcl>
1: 94.99610 94.99608 94.99613   TRUE
2: 95.00561 95.00558 95.00566  FALSE

数据

df1 <- structure(list(weight = c(94.9961, 95.00561), low = c(94.99608, 
95.00558), high = c(94.99613, 95.00566)), class = "data.frame", row.names = c(NA, 
-2L))

df2 <- structure(list(index = 1:5, th_weight = c(94.996092, 95.496336, 
95.509906, 97.473292, 100.51906)), class = "data.frame", row.names = c(NA, 
-5L))