R语言中通话数据框的号码与时间模糊匹配问题排查
R语言通话记录匹配问题修复方案
需求说明
需匹配客户侧与供应商侧两份通话记录,匹配规则:
- 主叫号码(ANUM)、被叫号码(BNUM)完全一致
- 通话起始时间(SECONDS)的绝对值偏差不超过指定阈值(如5秒)
最终输出4份文件:
- 匹配成功的客户侧记录(保留原列)
- 匹配成功的供应商侧记录(与文件1维度一致,用于时长对比)
- 客户侧独有的通话记录
- 供应商侧独有的通话记录
原代码问题分析
原代码存在以下核心问题导致匹配结果维度不一致:
- 仅单向偏移时间(仅将供应商侧SECONDS加i),未考虑客户侧时间更大的情况
- 使用
semi_join仅提取单侧匹配记录,无法建立客户与供应商记录的一一对应关系 - 循环匹配逻辑会导致重复匹配同一记录,最终两边匹配集无对应关联
修复后的代码
library(readxl) library(dplyr) library(writexl) # 读取数据 datavendor <- read_excel("CDRS_VENDOR_1MARCH.xlsx") dataclient <- read_excel("CDRS_CLIENT_1MARCH.xlsx") # 类型转换:确保关键字段类型一致,同时添加唯一标识用于关联 dataclient <- dataclient %>% mutate( ANUM = as.numeric(ANUM), BNUM = as.numeric(BNUM), SECONDS = as.numeric(SECONDS), client_id = row_number() ) datavendor <- datavendor %>% mutate( ANUM = as.numeric(ANUM), BNUM = as.numeric(BNUM), SECONDS = as.numeric(SECONDS), vendor_id = row_number() ) # 定义时间偏差阈值 max_time_offset <- 5 # 生成所有符合规则的匹配对:ANUM/BNUM一致,时间差绝对值≤阈值 matched_pairs <- dataclient %>% inner_join(datavendor, by = c("ANUM", "BNUM"), suffix = c("_client", "_vendor")) %>% mutate(time_diff = abs(SECONDS_client - SECONDS_vendor)) %>% filter(time_diff <= max_time_offset) %>% # 处理一对多/多对一情况:保留时间差最小的唯一匹配 group_by(client_id) %>% slice_min(time_diff, n = 1, with_ties = FALSE) %>% ungroup() %>% group_by(vendor_id) %>% slice_min(time_diff, n = 1, with_ties = FALSE) %>% ungroup() # 提取匹配成功的记录 okclient <- dataclient %>% filter(client_id %in% matched_pairs$client_id) %>% select(-client_id) okvendor <- datavendor %>% filter(vendor_id %in% matched_pairs$vendor_id) %>% select(-vendor_id) # 提取未匹配的记录 unmatched_client <- dataclient %>% filter(!client_id %in% matched_pairs$client_id) %>% select(-client_id) unmatched_vendor <- datavendor %>% filter(!vendor_id %in% matched_pairs$vendor_id) %>% select(-vendor_id) # 写入文件 write_xlsx(okclient, "/Users/Downloads/Matched_client.xlsx") write_xlsx(okvendor, "/Users/Downloads/Matched_vendor.xlsx") write_xlsx(unmatched_client, "/Users/Downloads/Unmatched_client.xlsx") write_xlsx(unmatched_vendor, "/Users/Downloads/Unmatched_vendor.xlsx")
关键修复点说明
- 添加唯一标识:给两份数据分别添加
client_id和vendor_id,确保能精准关联匹配的记录 - 双向时间差过滤:通过计算两边SECONDS的绝对值偏差,覆盖所有时间偏差方向的情况
- 去重处理:用
slice_min确保一条记录仅匹配一条最接近的对应记录,避免重复匹配导致维度不一致 - 精准提取匹配记录:通过唯一标识筛选,确保
okclient和okvendor的记录是一一对应的,维度完全一致
数据样例注意事项
从提供的样例数据来看,客户侧的SECONDS(如3244)与供应商侧的SECONDS(如37)数值差异极大,需确认SECONDS是否包含日期维度(多日分析时需将日期转换为秒数加入计算),否则会导致匹配逻辑失效。
内容的提问来源于stack exchange,提问作者CLARA
相关产品推荐
相关产品推荐

