【发布时间】:2015-08-24 21:28:34
【问题描述】:
我有一个包含三列的数据框Data1:NoContract、IniDate、FinDate 分别代表合约的标识符,合约何时开始和何时结束。另一方面,我有一个分析期:2012 年 1 月 1 日至 2014 年 12 月 31 日。我想找出分析期内每个月有多少活跃的合约,活跃的意思是合约至少有一天IniDate 和 FinDate 之间的日期在一个月的分析期间。
我尝试在 R 中做:
假设Data1 是:
Data1 <- data.frame(NoContract= 1:3, IniDate= as.Date(c("2011-05-03","2012-03-13","2014-03-26")),FinDate=as.Date(c("2015-01-05","2013-03-13","2015-08-19")))
Data1
NoContract IniDate FinDate
1 1 2011-05-03 2015-01-05
2 2 2012-03-13 2013-03-13
3 3 2014-03-26 2015-08-19
我创建了另一个数据框 DatesCalc 为:
DatesCalc<-data.frame(monthI=seq(as.Date("2012-01-01"), as.Date("2014-12-31"), by="1 month"), monthF=(seq(as.Date("2012-02-01"), as.Date("2015-01-01"), by="1 month")-1))
head(DatesCalc)
monthI monthF
1 2012-01-01 2012-01-31
2 2012-02-01 2012-02-29
3 2012-03-01 2012-03-31
4 2012-04-01 2012-04-30
5 2012-05-01 2012-05-31
6 2012-06-01 2012-06-30
接下来,我写了一个函数
myfun<-function(X,Y){
d1<-numeric()
d2<-numeric()
for (i in 1:36){ #36 num of rows on DatesCalc
d1<-numeric()
for (j in 1:3){ #3 num of rows of my Data1 (my actual case near 550K rows)
d1<-c(d1,sum(seq(X[i,1],X[i,2],by=1)%in%seq(Y[j,2],Y[j,3],by=1),na.rm=TRUE)>0)
}
d2<-cbind(d2,d1)
}
return(d2)
}
所以它的作用是,对于Data1 的每一行,创建DatesCalc 每一行的日期序列,并证明它是否在Data1 的当前行的日期序列内。此函数返回一个矩阵,其中行表示合约,列表示从 2012 年 1 月到 2014 年 12 月的月份,如果合约在一个月内处于活动状态,则每个单元格都有1,如果没有,则有0(请参阅Res)。最后我用 apply 按列求和,得到了我想要的。
Res<-myfun(DatesCalc,Data1)
Res
d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1
[1,] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
[2,] 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1
apply(Res,2,sum)
d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1 d1
1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2
情况是我的实际Data1 中有数十万行(550K),并且在其上运行myfun 效率低下。我的问题是,也许是一种在 R 中有效的方法?或有关如何改进我的代码的任何建议。谢谢社区。p>
【问题讨论】:
-
这似乎是
foverlaps在data.table包中的一个案例。您会在 SO 上找到一些非常好的问答,例如here -
谢谢@Henrik 我会试试
foverlaps
标签: r date date-range