如果日期落在 R 中所有系列日期的日期范围内,则计算行

count row if date falls within date range for all dates in series in R

我有一个大数据框(约 30,000 行),其中有两个日期字段“start_date”和“end_date”。

我想总结数据,这样一列包含所有日期,第二列包含日期在“start_date”和“[=”之间的所有行的计数26=]".

我可以使用 2 个 for 循环完成这项工作,但它非常低效,因为它逐一比较大约 180 个日期和 30,000 行日期范围。

下面是一个例子。假设我有以下数据框。

df <- tibble(
  start_date = c(1,1,2,2,3,3,4,4,5,5),
  end_date = c(2,3,4,5,6,7,8,9,10,11)
)

我希望它输出一个 table/dataframe 看起来像这样的

Date    Count
1       2
2       4
3       5
4       6
5       7
6       6
7       5
8       4
9       3
10      2
11      1

是否有一些 TidyVerse 函数或其他任何可以有效执行此转换的函数?

这是一个基本的 R 方法:

date = seq(min(df$start_date), max(df$end_date))
count = sapply(date, \(x) sum(x >= df$start_date & x <= df$end_date))
data.frame(date, count)
#    date count
# 1     1     2
# 2     2     4
# 3     3     5
# 4     4     6
# 5     5     7
# 6     6     6
# 7     7     5
# 8     8     4
# 9     9     3
# 10   10     2
# 11   11     1

这是使用 foverlapsdata.table 方法。首先,从最小 start_date 到最大 end_date 创建所需日期的 sequence。然后,为每个日期创建一个简单的 data.table

使用 foverlaps 获取起始 data.frame 和新 table 之间的重叠连接。最后,计算每个日期连接后的行数。

library(data.table)

setDT(df)
dates <- seq(min(df$start_date), max(df$end_date), by = 1)
dt <- data.table(start_date = dates, end_date = dates, key = c("start_date", "end_date"))
foverlaps(df, dt, which = T)[, .N, by = yid]

输出

    yid N
 1:   1 2
 2:   2 4
 3:   3 5
 4:   4 6
 5:   5 7
 6:   6 6
 7:   7 5
 8:   8 4
 9:   9 3
10:  10 2
11:  11 1

tidyverse 中,您可以适应以下内容:

library(tidyverse)

data.frame(date = seq(min(df$start_date), max(df$end_date), by = 1)) %>%
  rowwise() %>%
  mutate(count = sum(date >= df$start_date & date <= df$end_date))