我有一个大数据帧(约30000行(,其中有两个日期字段"start_ date";以及";end_date";。
我想总结数据,使得我有一列包含所有日期,第二列包含所有行的计数;start_ date";以及";end_date";。
我可以使用2个for循环来完成这项工作,但效率非常低,因为它是一个接一个地比较大约180个日期和30000行日期范围。
下面是一个例子。假设我有以下数据帧。
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)
)
我希望它输出一个看起来像的表/数据帧
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
以下是使用foverlaps
的data.table
方法。首先,创建从最小start_date
到最大end_date
的所需日期的seq
影响。然后,为每个日期创建一个简单的data.table
。
使用foverlaps
获取起始数据帧和新表之间的重叠联接。最后,计算每个日期联接后的行数。
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))