如何在R中使用fastLink实现数值型字段的部分匹配?
问题:fastLink未识别预期的数值匹配案例
我正尝试使用fastLink关联两个数据集,发现部分手动匹配的案例未被fastLink识别,为此进行了测试:
library(fastLink) a <- data.frame("x"=1:40, "date"=c(3603, 3603, 4115, 3805, 4448, 4448, 4758, 4758, 4758, 4623, 4623, 4623, 4623, 4623, 4623, 4623, 4623, 4667, 4667, 4840, 4840, 4840, 4693, 4623, 6247, 5715, 6227, 6227, 5988, 6331, 6331, 5988, 6268, 6268, 6268, 6268, 6275, 6275, 5829, 6275)) b <- data.frame("x"=1:82, "date"=c(3042, 3104, 3302, 3330, 3342, 3407, 3713, 3882, 3882, 4043, 4249, 4175, 4184, 4184, 4184, 4366, 4239, 4117, 4127, 4127, 4239, 4498, 5094, 4848, 4975, 5148, 5185, 5213, 5309, 5521, 5604, 5604, 5604, 5604, 5897, 5976, 5976, 6002, 6058, 6102, 6158, 6184, 6184, 6184, 6184, 6255, 6256, 6256, 6275, 6275, 6284, 6284, 6284, 6303, 6303, 6312, 6332, 6340, 6352, 6352, 6366, 6366, 6366, 6366, 6366, 6366, 6367, 6375, 6375, 6396, 6403, 6407, 6443, 6443, 6443, 6443, 6494, 6494, 6494, 6494, 6494, 6494)) out <- fastLink(a, b, varnames="date", numeric.match="date", threshold.match=.01) key_tab <- data.frame("inds.a"=out$matches$inds.a, "inds.b"=out$matches$inds.b, "a_date"=unlist(a[out$matches$inds.a, "date"]), "b_date"=unlist(b[out$matches$inds.b, "date"]), "posterior"=out$posterior) key_tab inds.a inds.b a_date b_date posterior 1 37 49 6275 6275 0.7025187055498182 2 38 50 6275 6275 0.7025187055498182 3 40 50 6275 6275 0.7025187055498182 4 30 57 6331 6332 0.7025187055498182 5 31 57 6331 6332 0.7025187055498182
测试结果显示fastLink仅返回5条匹配,其中3条为完全匹配,2条为差值1的匹配(因默认cut.a.num=1,差值1被视为完全匹配)。但数据中存在差值2、3的匹配,却未被返回。我尝试了以下操作均未解决:
- 设置
cut.p.num=3/2/5/100无变化 - 添加
partial.match="date"后无匹配返回 - 设置
dedupe.matches=FALSE仅增加上述5条的匹配数 - 设置
return.all=TRUE后无匹配返回
原因分析及解决方法
原因
fastLink的数值匹配逻辑中,numeric.match参数仅处理完全匹配或cut.a.num范围内的近似匹配,你需要的差值2、3的匹配超出了默认的cut.a.num=1范围。此外:
cut.p.num是按百分比设置阈值,不是绝对差值,你的日期数值较大,百分比阈值对应的绝对差值远大于你需要的范围,因此设置后无效果。partial.match是针对字符串的部分匹配规则,不适用于数值型变量,添加后自然不会返回匹配结果。
解决方法
方法1:调整cut.a.num参数
直接修改cut.a.num为你需要的最大绝对差值(比如3),让fastLink自动识别差值在该范围内的匹配候选:
out <- fastLink(a, b, varnames="date", numeric.match="date", cut.a.num=3, # 设置允许的最大绝对差值 threshold.match=.01) key_tab <- data.frame("inds.a"=out$matches$inds.a, "inds.b"=out$matches$inds.b, "a_date"=unlist(a[out$matches$inds.a, "date"]), "b_date"=unlist(b[out$matches$inds.b, "date"]), "posterior"=out$posterior) key_tab
此方法会将所有date差值≤3的记录纳入匹配候选池,再通过threshold.match控制后验概率筛选最终匹配结果。
方法2:自定义候选匹配对(进阶)
如果需要更精准的匹配规则,可以手动生成所有符合差值条件的候选对,再传入fastLink计算匹配概率:
# 生成所有date差值≤3的候选对 candidates <- expand.grid(inds.a=1:nrow(a), inds.b=1:nrow(b)) candidates$diff <- abs(a$date[candidates$inds.a] - b$date[candidates$inds.b]) candidates <- candidates[candidates$diff <=3, ] # 传入自定义候选对进行匹配计算 out <- fastLink(a, b, varnames="date", numeric.match="date", threshold.match=.01, candidates=candidates) # 使用手动筛选的候选对 key_tab <- data.frame("inds.a"=out$matches$inds.a, "inds.b"=out$matches$inds.b, "a_date"=unlist(a[out$matches$inds.a, "date"]), "b_date"=unlist(b[out$matches$inds.b, "date"]), "posterior"=out$posterior) key_tab
这种方式跳过fastLink默认的候选对筛选逻辑,精准控制进入匹配计算的记录对,避免遗漏目标匹配。
内容的提问来源于stack exchange,提问作者Elizabeth
相关产品推荐
相关产品推荐

