【问题标题】:How do I check if each row in a column falls between a range of two other columns?如何检查列中的每一行是否位于其他两列的范围之间?
【发布时间】:2018-06-22 02:00:36
【问题描述】:

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

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

【问题讨论】:

  • 听起来像是一个非 equi 自连接,给你一些搜索词来扩大范围
  • 只是一个普通的非 equi 连接。某事like this.
  • 谢谢你们!!我将进一步研究这些连接。前几天晚上花了几个小时想办法做到这一点

标签: r data.table


【解决方案1】:

正如评论中所说,这是一个常规的非 equi 连接。一种方法是:

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 &gt;= LowID, CheckID &lt;= HighID) 指定连接条件,i.HighID 指的是DT2 中的HighID 列。

NA 行是您要放置“False”的位置,但您不能对数字列执行此操作,除非您将其转换为字符列。

【讨论】:

  • 非常感谢先生。我将用我的完整数据集试一试,让你知道性能!
  • 再次感谢您。这是指数级地更快和更清洁!数据表是要走的路。
猜你喜欢
  • 2019-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-05
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多