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

检查数据框日期是否在另一数据框对应时间范围内(R语言)

Efficiently Match Dates to Event Ranges in Large R Datasets

Hey there! Let's work through this problem, with a focus on keeping things efficient for your large 500k+ row dataset. First, let's recap your input data and requirements clearly.

Your Input Data

First, here's the original data you're working with:

# Main date dataset
df <- data.frame(
  id = c("AED","AED","CFR","DRR","DRR","DRR","UN","PO"),
  dates = as.POSIXct(c("2018-05-17 09:52:00","2018-05-17 10:49:00","2018-05-17 10:38:00","2018-05-17 11:29:00","2018-05-17 12:12:00","2018-05-17 13:20:00","2018-05-17 14:28:00","2018-05-17 15:59:00"))
)

# Event time ranges dataset
events <- data.frame(
  id = c("AED","CFR","DRR","DRR","UN"),
  start = as.POSIXct(c("2018-05-17 10:00:00","2018-05-17 10:18:00","2018-05-17 11:18:00","2018-05-17 13:10:00","2018-05-17 14:18:00")),
  end = as.POSIXct(c("2018-05-17 11:56:00","2018-05-17 12:23:00","2018-05-17 12:01:00","2018-05-17 14:18:00",NA))
)

Requirements

You need to add two columns (inRange and outsideRange) to df with these rules:

  • If an id from df doesn't appear in events, both columns should be FALSE
  • If a df$dates falls within any of the corresponding id's event ranges (or is after start when end is NA), inRange = TRUE and outsideRange = FALSE
  • If an id exists in events but the date doesn't fall in any range, inRange = FALSE and outsideRange = TRUE

Optimized Solution for Large Datasets (using data.table)

For datasets with 500k+ rows, data.table is the best choice—it's optimized for speed and memory efficiency. Here's how to get your desired result:

library(data.table)

# Convert data frames to data.tables (enables faster operations)
setDT(df)
setDT(events)

# Join df with events by id, creating all id-date-event combinations
temp <- df[events, on = .(id), allow.cartesian = TRUE]

# Calculate if each date falls within the corresponding event range
temp[, inRange := (dates > start) & (is.na(end) | dates <= end)]

# Group by id and date to check if any event range includes the date
result_dt <- temp[, .(
  inRange = any(inRange, na.rm = TRUE),
  dates = first(dates)
), by = .(id, dates)]

# Calculate outsideRange: only TRUE if id exists in events AND inRange is FALSE
result_dt[, outsideRange := (id %in% events$id) & !inRange]

# For ids not in events, set both columns to FALSE (matches your rule)
result_dt[id %notin% events$id, `:=`(inRange = FALSE, outsideRange = FALSE)]

# Reorder columns to match your desired output
setcolorder(result_dt, c("id", "dates", "inRange", "outsideRange"))

# Convert back to data.frame if you prefer that format
result <- as.data.frame(result_dt)

# View the final result
print(result)

Alternative Tidyverse Solution (using dplyr)

If you prefer the tidyverse syntax, here's a working version—note this will be slower for very large datasets compared to data.table, but still functional:

library(dplyr)

result <- df %>%
  # Join with events to get all matching ranges for each id-date
  left_join(events, by = "id") %>%
  # Check if date falls within each individual range
  mutate(inRange = (dates > start) & (is.na(end) | dates <= end)) %>%
  # Group by id and date to check if any range includes the date
  group_by(id, dates) %>%
  summarise(inRange = any(inRange, na.rm = TRUE), .groups = "drop") %>%
  # Calculate outsideRange and handle ids not in events
  mutate(
    outsideRange = (id %in% events$id) & !inRange,
    inRange = ifelse(id %in% events$id, inRange, FALSE),
    outsideRange = ifelse(id %in% events$id, outsideRange, FALSE)
  ) %>%
  # Preserve the original order of rows from df
  arrange(match(paste(id, dates), paste(df$id, df$dates)))

print(result)

Verifying the Result

Both solutions will produce exactly the output you specified:

# Output matches your desired result
print(result)
#>    id               dates inRange outsideRange
#> 1 AED 2018-05-17 09:52:00   FALSE         TRUE
#> 2 AED 2018-05-17 10:49:00    TRUE        FALSE
#> 3 CFR 2018-05-17 10:38:00    TRUE        FALSE
#> 4 DRR 2018-05-17 11:29:00    TRUE        FALSE
#> 5 DRR 2018-05-17 12:12:00   FALSE         TRUE
#> 6 DRR 2018-05-17 13:20:00    TRUE        FALSE
#> 7  UN 2018-05-17 14:28:00    TRUE        FALSE
#> 8  PO 2018-05-17 15:59:00   FALSE        FALSE

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:11:05