R语言基于data.table实现两表区间重叠匹配的问题
区间重叠匹配的正确实现方案
原代码的错误原因
- 连接条件仅用表
r的区间右端点re和表f的区间做匹配,没有覆盖两个区间重叠的完整判定逻辑。数学上两个闭区间[rs, re]和[fs, fe]存在重叠的充要条件是:rs <= fe 且 re >= fs,原代码仅判断了re是否落在f的区间内,完全遗漏了对区间起点的判断,导致类似iv、vi这类区间跨越f边界的行匹配错误。 - 后续使用
nafill(flen, 'locf')做向下填充属于错误补值逻辑:未匹配上的行并不是靠“取上一行的非空值”就能得到正确结果,反而会把不属于本行的区间值错误套用到当前行。
正确实现方法
方法1:data.table 规范模糊连接
直接把区间重叠的判定规则作为连接条件写入on参数,因为示例中表f的两个区间完全无重叠,每一行r的区间最多只会匹配到1个f的区间,不需要额外的填充操作:
library(data.table) # 转换为data.table格式 setDT(r) setDT(f) # 按区间重叠规则匹配对应fl值 r[f, flen := fl, on = .(rs <= fe, re >= fs)]
运行后输出结果和预期完全一致:
rn rs re flen 1: i 1 10 10 2: ii 21 30 15 3: iii 3 17 10 4: iv 23 42 15 5: v 6 18 10 6: vi 28 43 15 7: vii 7 11 10 8: viii 26 31 15
方法2:基础R快速匹配
因为示例中表f的区间是按从小到大排序、无重叠的,可直接用findInterval快速定位每个r区间对应的f条目,不需要加载额外包:
# 以r区间的中点为参照,定位落在f的哪个区间内 r$flen <- f$fl[findInterval((r$rs + r$re)/2, f$fs)]
该方法的运行结果和上述data.table方案完全一致。
注:如果后续存在某行
r的区间同时跨多个f的区间的场景,上述两种单值匹配的逻辑需要调整为返回所有匹配的fl值,不过在当前示例的数据结构下完全适用。
内容的提问来源于stack exchange,提问作者Digsby
相关产品推荐
相关产品推荐

