R:日期之间的天数

Mik*_*ike 1 r date seq

我有以下数据帧:

AllDays  
2012-01-01  
2012-01-02  
2012-01-03  
...  
2015-08-18  

Leases 
StartDate  EndDate
2012-01-01 2013-01-01  
2012-05-07 2013-05-06  
2013-09-05 2013-12-01   
Run Code Online (Sandbox Code Playgroud)

我想要做的是,对于allDays数据帧中的每个日期,计算有效的租约数量.例如,如果有4个租约的开始日期<= 2015-01-01和结束日期> = 2015-01-01,那么我想在该数据帧中放置一个4.

我有以下代码

  for (i in 1:nrow(leases))
  {
    occupied = seq(leases$StartDate[i],leases$EndDate[i],by="days")
    occupied = occupied[occupied < dateOfInt]
    matching = match(occupied,allDays$Date)
    allDays$Occupancy[matching] = allDays$Occupancy[matching] + 1
  }
Run Code Online (Sandbox Code Playgroud)

这是有效的,但由于我有大约5000个租约,它需要大约1.1秒.有没有人有更有效的方法需要更少的计算时间?利息日仅为当前日期,仅用于确保未计入未来的租赁日期.

Mic*_*ico 5

使用seq几乎肯定是效率低下的-假设您的数据租约长达10,000年。seq将会花费永远,并返回对我们无关紧要的10000 * 365-1天。然后,我们必须使用%in%它进行相同数量的不必要的比较。

我不确定以下方法是否是最佳方法(我相信有一个完全矢量化的解决方案),但是它离问题的核心越来越近。

数据

set.seed(102349)
days<-data.frame(AllDays=seq(as.Date("2012-01-01"),
                             as.Date("2015-08-18"),"day"))

leases<-data.frame(StartDate=sample(days$AllDays,5000L,T))
leases$EndDate<-leases$StartDate+round(rnorm(5000,mean=365,sd=100))
Run Code Online (Sandbox Code Playgroud)

方法

使用data.tablesapply

library(data.table)
setDT(leases); setDT(days)

days[,lease_count:=
       sapply(AllDays,function(x)
         leases[StartDate<=x&EndDate>=x,.N])][]
         AllDays lease_count
   1: 2012-01-01           5
   2: 2012-01-02           8
   3: 2012-01-03          11
   4: 2012-01-04          16
   5: 2012-01-05          18
  ---                       
1322: 2015-08-14        1358
1323: 2015-08-15        1358
1324: 2015-08-16        1360
1325: 2015-08-17        1363
1326: 2015-08-18        1359
Run Code Online (Sandbox Code Playgroud)


Kha*_*haa 5

这正是foverlaps闪耀的问题:基于另一个data.frame对data.frame进行子集化(foverlaps似乎是为此目的而定制的).

基于@ MichaelChirico的数据.

setkey(days[, AllDays1:=AllDays,], AllDays, AllDays1)
setkey(leases, StartDate, EndDate)
foverlaps(leases, days)[, .(lease_count=.N), AllDays]
#   user  system elapsed 
#  0.114   0.018   0.136
# @MichaelChirico's approach
#   user  system elapsed 
#  0.909   0.000   0.907 
Run Code Online (Sandbox Code Playgroud)

以下是@Arun如何工作的简要说明,让我开始使用data.table.

  • 这应该是公认的答案.. :-(.并且很谦虚地知道那个答案让你开始使用dt. (2认同)