准备数据并确保日期列实际存储为日期:
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 上结束,因此从 12 月开始的任何日期都不会包含在 seq 中。最后一行将日期转换为仅包含年和月的字符。
现在,您可以使用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