You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于区间条件合并R语言DataFrame,实现多输出行展开

区间匹配合并DataFrame并保留多匹配结果

问题背景

需要将两个DataFrame按区间条件合并:主数据框df1需保留原有结构逻辑,df2提供匹配用的区间条件与输出变量var.out。匹配规则为var.start >= (start - 2) & var.end <= (end + 2),要求所有符合条件的匹配结果都保留(包括同一df1行匹配多个var.out的情况),而非出现空值。

df1结构

df1 <- data.frame(
  id = c("id-0023","id-0023","id-0023","id-0023","id-0023","id-0023","id-0150","id-0150","id-0150","id-0181","id-0181","id-0181","id-0181"),  
  var1 = "task01",
  var2 = c(0,0,0,2,2,4,2,4,4,2,2,4,4),
  var.start = c(161,505,796,4,131,389,364,425,782,140,181,569,753),
  var.end = c(228,526,820,55,389,941,389,470,941,176,482,631,782))

print(df1)

df2结构

df2 <- data.frame(
    var1 = "task01",
    var2 = c(0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,4,4,4,4,4,4,4),
    start = c(0,143,410,741,821,919,1135,0,200,269,391,481,516,646,808,946,972,1181,0,206,386,539,555,632,782),
    end = c(143,410,741,821,919,1135,1295,200,269,391,481,516,646,808,946,972,1181,1331,206,386,539,555,632,782,941),
    var.out = c(2,2,2,4,3,4,3,4,4,3,2,4,3,3,2,1,2,2,4,2,3,1,3,4,3))
    
print(df2)

原代码问题

原代码通过full_join+filter+right_join的方式尝试合并,但当df1的某一行匹配到多个df2的var.out时,无法保留所有匹配结果,反而出现空值,不符合需求。

解决方案

直接通过inner_join先关联共同字段,过滤符合区间条件的行,再处理区间包含的情况(将df1的大区间替换为df2的小区间),最终得到所有匹配结果:

library(dplyr)

output <- df1 %>%
  # 先按共同字段var1、var2关联两个数据框
  inner_join(df2, by = c("var1", "var2")) %>%
  # 过滤符合区间匹配条件的行
  filter(var.start >= (start - 2) & var.end <= (end + 2)) %>%
  # 处理df1区间包含df2区间的情况,替换为df2的区间值
  mutate(
    var.start = ifelse(var.start <= start & var.end >= end, start, var.start),
    var.end = ifelse(var.start <= start & var.end >= end, end, var.end)
  ) %>%
  # 选择目标列并排序
  select(var1, id, var2, var.start, var.end, var.out) %>%
  arrange(id, var2, var.start, var.end)

# 输出结果
print(output)

运行上述代码后,输出结果将与指定的desired.output结构完全一致,所有匹配到的var.out都会以独立行的形式保留。

内容的提问来源于stack exchange,提问作者xidelos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 08:20:34