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

基于时间范围统计另一数据框中记录的出现次数

解决方案:按ID与时间范围统计观测数量

以下是几种针对需求的可行方法,均能保留df2的所有行(包括重复ID):

方法1:使用dplyr逐行处理(直观易读)

该方法通过rowwise()实现逐行判断,逻辑清晰,适合理解和调试:

library(dplyr)

# 定义原始数据框
df1 <- data.frame(
  ID = c("a", "b", "a", "c", "a", "b"), 
  date = as.Date(c("2020-1-1", "2020-1-2", "2020-1-5","2020-1-10", "2020-1-10", "2020-1-15"))
)

df2 <- data.frame(
  ID = c("a", "b", "a", "c"), 
  start = as.Date(c("2019-12-30", "2020-1-1", "2020-1-5","2020-1-10")), 
  end = as.Date(c("2020-1-3", "2020-1-2", "2020-1-12","2020-1-14"))
)

# 逐行统计符合条件的记录数
df3 <- df2 %>%
  rowwise() %>%
  mutate(count = nrow(filter(df1, ID == !!ID, date >= start, date <= end))) %>%
  ungroup()

# 转换count为字符型(匹配预期结果格式)
df3$count <- as.character(df3$count)

方法2:使用data.table非等连接(高效适合大数据)

如果数据量较大,data.table的非等连接性能更优,且能精准保留df2的所有行:

library(data.table)

# 转换为data.table格式
df1 <- data.table(
  ID = c("a", "b", "a", "c", "a", "b"), 
  date = as.Date(c("2020-1-1", "2020-1-2", "2020-1-5","2020-1-10", "2020-1-10", "2020-1-15"))
)

df2 <- data.table(
  ID = c("a", "b", "a", "c"), 
  start = as.Date(c("2019-12-30", "2020-1-1", "2020-1-5","2020-1-10")), 
  end = as.Date(c("2020-1-3", "2020-1-2", "2020-1-12","2020-1-14"))
)

# 非等连接并按df2每行统计数量
count_df <- df2[df1, on = .(ID, start <= date, end >= date), 
                .(count = .N), by = .EACHI]

# 合并回原df2的所有列并调整格式
df3 <- merge(df2, count_df, by = c("ID", "start", "end")) %>%
  setcolorder(c("ID", "start", "end", "count")) %>%
  .[, count := as.character(count)]

方法3:使用Base R的apply函数(无需第三方包)

若不想加载额外包,可直接用base R的apply函数实现需求:

# 定义原始数据框
df1 <- data.frame(
  ID = c("a", "b", "a", "c", "a", "b"), 
  date = as.Date(c("2020-1-1", "2020-1-2", "2020-1-5","2020-1-10", "2020-1-10", "2020-1-15"))
)

df2 <- data.frame(
  ID = c("a", "b", "a", "c"), 
  start = as.Date(c("2019-12-30", "2020-1-1", "2020-1-5","2020-1-10")), 
  end = as.Date(c("2020-1-3", "2020-1-2", "2020-1-12","2020-1-14"))
)

# 逐行计算符合条件的记录数
df2$count <- apply(df2, 1, function(row) {
  sum(df1$ID == row["ID"] & df1$date >= as.Date(row["start"]) & df1$date <= as.Date(row["end"]))
})

# 转换为字符型并命名为df3
df2$count <- as.character(df2$count)
df3 <- df2

以上三种方法最终都能得到你预期的df3结果,可根据数据量和个人习惯选择。

内容的提问来源于stack exchange,提问作者Tan Sing Chee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:15:16