R:转换的开始/结束日期,数据系列

问题描述:

我有以下的数据帧代表用户订阅:R:转换的开始/结束日期,数据系列

User StartDate EndDate 
1  2015-09-03 2015-10-17 
2  2015-10-27 2015-12-25 
... 

我怎样才能将其转化为一个时间序列,让我随着时间的推移活性每月订阅的计数(假设该月至少在一个月内有效)。像这样的东西(根据上面的例子中,假设只有2条):

Month Count 
2015-08 0 
2015-09 1 
2015-10 2 
2015-11 1 
2015-12 1 
2016-01 0 

REM:我花了一些任意的开始和结束日期为时间序列,使例子清晰。

准备数据,并确保该日期列,实际存储为日期:

data <- read.table(text = "User StartDate EndDate 
1  2015-09-03 2015-10-17 
2  2015-10-27 2015-12-25", header = TRUE) 
data$StartDate <- as.Date(StartDate) 
data$EndDate <- as.Date(EndDate)) 

该函数返回的所有月份是订阅内的一个矢量:

library(lubridate) 
subscr_month <- function(start, end) { 

    start <- floor_date(start, "month") 
    seq <- seq(start, end, by = "1 month") 
    months <- format(seq, format = "%Y-%m") 
    return(months) 

} 

它使用来自lubridate包的功能floor_date()。有必要整理开始日期,否则上个月可能会丢失。例如,对于用户2,如果您将两个月添加到开始日期,则最终将在结束日期之后的2015-12-27之后,以便在seq之前没有包含来自12月的日期。最后一行将日期转换为仅包含年份和月份的字符。

现在,您可以使用mapply()从您的数据中将这个函数应用于每个开始日期和结束日期。此后,table()会在结果列表中的所有日期的计数表:

all_month <- mapply(subscr_month, data$StartDate, data$EndDate, SIMPLIFY = FALSE) 
table(unlist(all_month)) 
## 2015-09 2015-10 2015-11 2015-12 
##  1  2  1  1 

您还可以将表格转换成数据帧:

as.data.frame(table(unlist(all_month))) 
##  Var1 Freq 
## 1 2015-09 1 
## 2 2015-10 2 
## 3 2015-11 1 
## 4 2015-12 1 

你的榜样输出也包括计数个月没有出现在数据集中。如果你想拥有这一点,你可以在数月的向量转换为一个因素,并设置级别给所有要包括月:

month_list <- format(seq(as.Date("2015-08-01"), as.Date("2016-01-01"), by = "1 month"), format = "%Y-%m") 
all_month_factor <- factor(unlist(all_month), levels = month_list) 
table(all_month_factor) 
## all_month_factor 
## 2015-08 2015-09 2015-10 2015-11 2015-12 2016-01 
##  0  1  2  1  1  0 

读提到的数据帧。

df = structure(list(StartDate = structure(c(16681, 16735), class = "Date"), 
    EndDate = structure(c(16735, 16794), class = "Date")), class = "data.frame", .Names = c("StartDate", 
"EndDate"), row.names = c(NA, -2L)) 

能否利用好dodplyr包和seq

df %>% 
     rowwise() %>% do({ 
     w <- seq(.$StartDate,.$EndDate,by = "15 days") #for month difference less than 1 complete month 
     m <- format(w,"%Y-%m") %>% unique 
     data.frame(Month = m) 
     }) %>% 
     group_by(Month) %>% 
     summarise(Count = length(Month))