如何在R中实现区间嵌套的DataFrame合并与结果计算
区间嵌套合并两个DataFrame的问题
我需要对两个包含区间的DataFrame进行嵌套合并,根据区间重叠关系计算新增列,具体场景和数据如下:
原始数据
df1 <- data.frame( type = rep("A", 6), start = c(66, 753, 1436, 2121, 8080, 8982), end = c(752, 1435, 2120, 2805, 8972, 9312), col1 = c(97.384, 97.23, 97.522, 97.522, 97.522, 97.376), col2 = c(686, 682, 684, 684, 892, 330) ) df2 <- data.frame( name = c("apple", "apple"), start = c(651, 8009), end = c(7964, 9314), val = c(71298, 1982), ave_val = c(9.749487215, 1.518773946) )
需求说明
新增cover(覆盖长度)和result(计算结果)列,规则如下:
- 若df1的区间与df2的区间部分重叠:
cover为两个区间的重叠长度,result = cover × df2$ave_val - 若df1的区间完全包含在df2的区间内:
cover为df1区间的长度(end - start + 1),result = df1$col2 × df2$ave_val
期望输出
| 类型(type) | 起始(start) | 结束(end) | 列1(col1) | 列2(col2) | 覆盖长度(cover) | 计算结果(result) |
|---|---|---|---|---|---|---|
| A | 66 | 752 | 97.384 | 686 | 101 | 984.698209 |
| A | 753 | 1435 | 97.23 | 682 | 682 | 6649.15028 |
| A | 1436 | 2120 | 97.522 | 684 | 684 | 6668.64925 |
| A | 2121 | 2805 | 97.522 | 684 | 684 | 6668.64925 |
| A | 8080 | 8972 | 97.522 | 892 | 892 | 1354.74636 |
| A | 8982 | 9312 | 97.376 | 330 | 330 | 501.195402 |
解决方案
可以使用dplyr结合fuzzyjoin包实现区间匹配,再完成逻辑判断和计算:
# 加载所需包 library(dplyr) library(fuzzyjoin) # 模糊连接匹配重叠区间,计算目标列 result_df <- fuzzy_inner_join( df1, df2, by = c("start" = "end", "end" = "start"), match_fun = list(`<=`, `>=`) ) %>% mutate( # 计算重叠区间的起止点 overlap_start = pmax(start.x, start.y), overlap_end = pmin(end.x, end.y), # 计算覆盖长度 cover = overlap_end - overlap_start + 1, # 判断df1区间是否完全被df2包含 is_fully_contained = (start.x >= start.y) & (end.x <= end.y), # 根据规则计算result result = ifelse(is_fully_contained, col2 * ave_val, cover * ave_val) ) %>% # 调整列名和顺序匹配期望输出 select( `类型(type)` = type, `起始(start)` = start.x, `结束(end)` = end.x, `列1(col1)` = col1, `列2(col2)` = col2, `覆盖长度(cover)` = cover, `计算结果(result)` = result ) # 查看最终结果 print(result_df)
代码说明
- 模糊连接:通过
fuzzy_inner_join筛选出两个区间存在重叠的行,匹配逻辑为df1$start <= df2$end且df1$end >= df2$start,确保只保留有效重叠配对。 - 重叠计算:用
pmax和pmin获取重叠区间的起止点,进而算出覆盖长度。 - 包含判断:通过区间起止点的大小关系,判断df1区间是否完全被df2区间包含。
- 结果生成:根据判断结果选择对应公式计算
result,最后调整列名和顺序以匹配期望输出格式。
内容的提问来源于stack exchange,提问作者Yuto Best boy
相关产品推荐
相关产品推荐

