2015-06-22 143 views
2

我有一個包含項目的數據框,並且每個項目都有開始日期和結束日期。我想知道一段時間內每天有多少活動項目。如何計算R中開始日期結束日期間隔的記錄?

示例數據集中:

ItemId <- c(1,2,3) 
StartDate <- c(ymd("2014-01-01"),ymd("2014-02-01"),ymd("2014-03-01")) 
EndDate <- c(ymd("2014-02-15"),ymd("2014-02-07"),ymd("2014-03-03")) 
data.frame(ItemId,StartDate,EndDate) 
    ItemId   StartDate    EndDate 
1  1 2014-01-01 01:00:00 2014-02-15 01:00:00 
2  2 2014-02-01 01:00:00 2014-02-07 01:00:00 
3  3 2014-03-01 01:00:00 2014-03-03 01:00:00 

結果應該是這個樣子(每天一個條目):

Date  ActiveCount 
2014-01-01 1 
2014-01-02 1 
... 
2014-02-01 2 
... 

我使用sqldf有一個解決方案,但不知道該怎麼辦這在R.

select d.date 
,  (select count(ItemID) 
     from items 
     where startdate <= d.date 
     and enddate >= d.date 
     ) activecount 
from (select distinct startdate from items 
     union 
     select distinct enddate from items 
     ) d 
order by 1 

(我每天都會有多個條目,所以對於R中的sqlite這個工作。 ostgresql我可以生成一系列更好的日期。)

謝謝。

+0

查看'data.table'包中的'foverlaps()'。或者在SO上搜索它。 – Arun

+0

請注意,sql語句可以使用'where d.date在startdate和enddate'之間。 –

回答

3

當的R任務類似於SQL的任務,它可能是時間,使dplyr出櫃:

library(dplyr) 
ItemId <- c(1,2,3) 
StartDate <- c(ymd("2014-01-01"),ymd("2014-02-01"),ymd("2014-03-01")) 
EndDate <- c(ymd("2014-02-15"),ymd("2014-02-07"),ymd("2014-03-03")) 

jim <- data.frame(ItemId,StartDate,EndDate) 

# One technique that's often useful especially in R, is to take your 
# iterator, and define it as a variable. You can use that to implement 
# a vectorised version of whatever you were thinking of doing.*/ 

ed <- data.frame(rng = seq(min(jim$StartDate), max(jim$EndDate), by = 'day')) 
merge(jim, ed, all=TRUE) %>% 
    filter(rng >= StartDate, rng <= EndDate) %>% 
    group_by(rng) %>% 
    summarise(n()) 

這就給你:

rng   n() 
1 2014-01-01 1 
2 2014-01-02 1 
3 2014-01-03 1 
... 
5

調用數據df

dates = seq(min(df$StartDate), max(df$EndDate), by = "day") 

counts = data.frame(date = dates, 
        count = sapply(dates, function(x) sum(x <= df$EndDate & x >= df$StartDate))) 
0

您首先要得到所有日期與至少一個活動項目,那麼你想指望每天活躍的項目數。如果我們存儲在itemDates您的數據,那麼這應該照顧它:

dates <- min(itemDates$StartDate) + days(0:as.numeric(max(itemDates$EndDate) - min(itemDates$StartDate))) 
dateCounts <- data.frame(
    row.names=dates, 
    counts=sapply(dates, function(date) 
     sum(date >= itemDates$StartDate & date <= itemDates$EndDate))) 
相關問題