在不循环R的情况下创建位矩阵

时间:2016-08-09 22:40:20

标签: r

我希望分析一组客户的会员差距,其中生效日期是其成员资格开始的地方,终止日期是其成员资格结束的时间。终止日期为2100-01-01表示当前成员。

我认为这样做的一个好方法是从我拥有的会员数据库中创建一个位矩阵。我希望会员ID为行,每天为列。

表格如下:

member_id|effective_date|termination_date
     1   | 2015-06-12   | 2015-12-19
     1   | 2016-03-17   | 2016-06-23
     2   | 2015-12-03   | 2100-01-01

我让它在多个循环中工作,但它需要永远。有哪些方法可以让我使用R更有效率。我的最终目标是识别过去一年中成员间距少于2的客户,差距小于60天。

感谢您的帮助。

编辑:我希望能够改变年份范围。我目前有

past_year = c(seq(as.Date('2015-07-01'),as.Date('2016-06-30'),'day'))

如果会员在我正在查看的范围内没有会员资格,我会考虑差距。在上面的例子中,过去年,他们不是2015-07-01和2016-06-30之间的成员。表中的两名成员都被认为有差距。

1 个答案:

答案 0 :(得分:1)

也许是这样的剧本。

dplyr库对于这些类型的聚合非常方便。加载并创建一些示例数据:

library(dplyr)

data.example <- data.frame(
  member_id = c(1, 1, 2, 3),
  effective_date = as.Date(c('2015-06-12', '2016-03-17', '2015-12-03', '2010-01-01')),
  termination_date = as.Date(c('2015-12-19', '2016-06-23', '2100-01-01', '2010-02-01'))
)

您的年份范围只有两个值:

past_year = as.Date(c('2015-07-01', '2016-06-30'))

将您的分析限制为仅包含您所在范围内日期的成员:

data.in.range <- subset(data.example, 
                       !((termination_date < min(past_year) & effective_date < min(past_year)) | 
                       (termination_date > max(past_year) & effective_date > max(past_year)))
                )

计算此会员拥有会员资格的天数,并报告是否有超过1个会员期,或会员资格的时间少于您的日期范围。

gaps <- group_by(data.in.range, member_id) %>% 
  summarize(
    num.entries = length(member_id),
    num.days = sum(termination_date - effective_date),
    has.gap = num.days < abs(diff(past_year)) | num.entries > 1
    )

  member_id num.entries       num.days has.gap
      <dbl>       <int> <S3: difftime>   <lgl>
1         1           2       288 days    TRUE
2         2           1     30710 days   FALSE

我不确定这是否正是您所追求的,但无论如何,计算范围应该比为范围的每一天创建位值并循环更快。