我通常使用dplyr
,但面对的数据集很大,而且我的方法非常慢。我基本上需要按日期过滤df
组,并计算
样本数据(已经将所有内容转换为data.table
)
library(data.table)
library(dplyr)
set.seed(123)
df <- data.table(startmonth = seq(as.Date("2014-07-01"),as.Date("2014-11-01"),by="months"),
endmonth = seq(as.Date("2014-08-01"),as.Date("2014-12-01"),by="months")-1)
df2 <- data.table(id = sample(1:10, 5, replace = T),
start = sample(seq(as.Date("2014-07-01"),as.Date("2014-10-01"),by="days"),5),
end = df$startmonth + sample(10:90,5, replace = T)
)
#cross joining
res <- setkey(df2[,c(k=1,.SD)],k)[df[,c(k=1,.SD)],allow.cartesian=TRUE][,k:=NULL]
我的dplyr
方法有效,但是很慢
res %>% filter(start <=endmonth & end>= startmonth) %>%
group_by(startmonth,endmonth) %>%
summarise(countmonth=n())
我的data.table
知识是有限的,但我想我们会setkeys()
在日期列和类似res[ , :=( COUNT = .N , IDX = 1:.N ) , by = startmonth, endmonth]
的位置上按组进行计数,但是我不确定过滤器如何进行在那里。
感谢您的帮助!
答案 0 :(得分:4)
您可以在联接中进行计数:
df2[df, on=.(start <= endmonth, end >= startmonth), allow.cartesian=TRUE, .N, by=.EACHI]
start end N
1: 2014-07-31 2014-07-01 1
2: 2014-08-31 2014-08-01 4
3: 2014-09-30 2014-09-01 5
4: 2014-10-31 2014-10-01 3
5: 2014-11-30 2014-11-01 3
或将其添加为df
中的新列:
df[, n :=
df2[.SD, on=.(start <= endmonth, end >= startmonth), allow.cartesian=TRUE, .N, by=.EACHI]$N
]
工作原理。语法为x[i, on=, allow.cartesian=, j, by=.EACHI]
。如果i
的每一行都用于在x
中查找值。符号.EACHI
表示将对j=.N
的每一行进行汇总(i
)。