R语言使用inner_join合并数据框返回行数远超原表问题咨询
R inner_join合并后行数远超原数据框问题排查
问题场景
现有两个各约1000万行的R数据框,执行以下合并代码:
df <- inner_join(frame1, frame2, by = c("id1" = "id2"))
最终得到的df行数达9000万行,远高于两个原数据框的行数。
产生原因
核心原因是连接键存在重复值,触发了多对多匹配的笛卡尔积效应:
dplyr的inner_join匹配逻辑为,frame1中每个id1对应的所有行,会和frame2中id2等于该值的所有行逐一匹配。如果某一个id值在frame1中有m条重复记录,在frame2中有n条重复记录,合并后该id对应的行数就是m*n,而非1:1匹配的行数。大量重复连接键累计后,就会出现总合并行数远高于原数据框行数的情况。
少数情况下也可能是连接键设置不符合业务逻辑导致:比如业务上需要id+日期两个字段才能唯一匹配行,但代码中仅设置了id作为唯一连接键,也会触发大量多余匹配。
解决方案
- 先排查连接键重复情况:分别统计两个数据框连接键的重复率,执行代码
sum(duplicated(frame1$id1))、sum(duplicated(frame2$id2))查看两个连接键的重复行数,确认重复是否符合业务预期。 - 补充连接键:如果连接键重复属于业务正常情况,加入更多共同字段作为匹配条件,缩小匹配范围,示例如下:
# 新增日期、业务类型两个匹配键 df <- inner_join(frame1, frame2, by = c("id1" = "id2", "date1" = "date2", "biz_type" = "biz_type")) - 先去重再合并:如果同id下的重复行属于数据冗余,先对两个数据框的连接键去重后再合并,保证1:1匹配:
# 保留每个id的第一条记录,其余字段全部保留 frame1_distinct <- distinct(frame1, id1, .keep_all = TRUE) frame2_distinct <- distinct(frame2, id2, .keep_all = TRUE) df <- inner_join(frame1_distinct, frame2_distinct, by = c("id1" = "id2")) - 提前校验匹配结果:全量合并前可以先抽取1%的样本做合并测试,验证行数是否符合预期,避免全量运算后得到无效大表占用内存资源。
内容的提问来源于stack exchange,提问作者hereforadoubt
相关产品推荐
相关产品推荐

