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

如何实现df2起止时间完全落入df1区间的R数据框精确连接?

问题:精确匹配完全包含的时间区间连接

我尝试用interval_left_join对两个带时间区间的数据框进行连接,但结果不符合预期。默认的interval_left_join只要df2的时间区间与df1的区间有端点重合就会匹配,而我需要的是df2的整个时间区间完全落入df1的对应区间内(即df2的Starttime_ms ≥ df1的Starttime_ms,且df2的Endtime_ms ≤ df1的Endtime_ms)。

数据框定义

df1 <- structure(list(Utterance = c("(5.127)", ">like how old 's your mom¿ ", 
                                "(0.855)", "eh six:ty:::-one= ", "(0.101)", "(0.166)", "=NOW ", 
                                "(0.622)", "!how! this always plays out  ", "(0.726)", "[when was] that¿= ", 
                                "[yes] ", "(0.163)", "=!this! was on °Wednesday° ", "(0.273)", 
                                "oka[y] "), Starttime_ms = c(0, 5127, 6830, 7685, 9889, 176800, 
                                                             176966, 177372, 177994, 179328, 180054, 180135, 180668, 180831, 
                                                             181720, 181993), Endtime_ms = c(5127, 6830, 7685, 9889, 9990, 
                                                                                             176966, 177372, 177994, 179328, 180054, 180668, 180555, 180831, 
                                                                                             181720, 181993, 182398)), row.names = c(NA, -16L), class = c("tbl_df", 
                                                                                                                                                          "tbl", "data.frame"))

df2 <- structure(list(Q_segment = c(">like I don 't understand< ", "sorry like how old 's your mom¿", 
                                    "[when was] that¿=", "=[did she let you in?]", "=holy [sh:]i:[:t", 
                                    "does it happen] often? ", "[like] ", "[what] type of:: tours is it ", 
                                    "is it [(like a long] ti:me¿", "[or]"), Starttime_ms = c(5127, 
                                                                                             5963, 180054, 253226, 345450, 347454, 348459, 478500, 480669, 
                                                                                             481763), Endtime_ms = c(5963, 6830, 180668, 254156, 347454, 348459, 
                                                                                                                     348724, 480669, 481763, 482000)), row.names = c(NA, -10L), class = c("tbl_df", 
                                                                                                                                                                                          "tbl", "data.frame"))

默认连接的问题

使用interval_left_join的默认逻辑会得到不符合需求的结果:

# 安装依赖包(如果未安装)
# if (!requireNamespace("BiocManager", quietly = TRUE))
#   install.packages("BiocManager")
# BiocManager::install("IRanges")
library(BiocManager)
library(fuzzyjoin)
library(data.table)

interval_left_join(x = df1,
                   y = df2,
                   by = c("Starttime_ms", "Endtime_ms"))

结果中出现了不需要的匹配,比如df1的(5.127)区间[0,5127]匹配了df2的>like...区间[5127,5963],以及df1的(0.855)区间[6830,7685]匹配了df2的how old...区间[5963,6830]——这些仅端点重合但区间并不包含的情况都被错误匹配了。

期望结果

仅保留df2区间完全落入df1区间内的匹配项:

Utterance                       Starttime_ms.x Endtime_ms.x Q_segment            Starttime_ms.y Endtime_ms.y
   <chr>                                    <dbl>        <dbl> <chr>                         <dbl>        <dbl>
 1 "(5.127)"                                    0         5127 NA                               NA           NA
 2 ">like how old 's your mom¿ "             5127         6830 >like                          5127         5963
 3 ">like how old 's your mom¿ "             5127         6830 how old 's your mom¿           5963         6830
 4 "(0.855)"                                 6830         7685 NA                               NA           NA
 5 "eh six:ty:::-one= "                      7685         9889 NA                               NA           NA
 6 "(0.101)"                                 9889         9990 NA                               NA           NA
 7 "(0.166)"                               176800       176966 NA                               NA           NA
 8 "=NOW "                                 176966       177372 NA                               NA           NA
 9 "(0.622)"                               177372       177994 NA                               NA           NA
10 "!how! this always plays out  "         177994       179328 NA                               NA           NA
11 "(0.726)"                               179328       180054 NA                               NA           NA
12 "[when was] that¿= "                    180054       180668 [when was] that¿=            180054       180668
13 "[yes] "                                180135       180555 NA                               NA           NA
14 "(0.163)"                               180668       180831 NA                               NA           NA
15 "=!this! was on °Wednesday° "           180831       181720 NA                               NA           NA
16 "(0.273)"                               181720       181993 NA                               NA           NA
17 "oka[y] "                               181993       182398 NA                               NA           NA

解决方案:自定义模糊匹配

使用fuzzy_left_join明确指定匹配条件,确保df2的区间完全被df1的区间包含:

library(fuzzyjoin)

fuzzy_left_join(
  x = df1,
  y = df2,
  by = c("Starttime_ms", "Endtime_ms"),
  match_fun = list(`<=`, `>=`)
)

这里的match_fun参数定义了严格的匹配规则:

  • 要求df2$Starttime_ms >= df1$Starttime_ms(对应df1$Starttime_ms <= df2$Starttime_ms)
  • 要求df2$Endtime_ms <= df1$Endtime_ms(对应df1$Endtime_ms >= df2$Endtime_ms)

运行这段代码后,就能得到符合期望的结果,仅保留df2区间完全落入df1区间内的匹配项。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 09:59:50