【问题标题】:Summarize consecutive failures with dplyr and rle用 dplyr 和 rle 总结连续失败
【发布时间】:2015-11-16 19:14:42
【问题描述】:

我正在尝试构建一个流失模型,其中包括每个客户的最大连续 UX 失败次数并遇到问题。这是我的简化数据和所需的输出:

library(dplyr)
df <- data.frame(customerId = c(1,2,2,3,3,3), date = c('2015-01-01','2015-02-01','2015-02-02', '2015-03-01','2015-03-02','2015-03-03'),isFailure = c(0,0,1,0,1,1))
> df
  customerId       date isFailure
1          1 2015-01-01         0
2          2 2015-02-01         0
3          2 2015-02-02         1
4          3 2015-03-01         0
5          3 2015-03-02         1
6          3 2015-03-03         1

想要的结果:

> desired.df
  customerId maxConsecutiveFailures
1          1                      0
2          2                      1
3          3                      2

我一直在胡思乱想,搜索其他 rle 问题并没有帮助我——这就是我“期待”的解决方案:

df %>% 
  group_by(customerId) %>%
  summarise(maxConsecutiveFailures = 
    max(rle(isFailure[isFailure == 1])$lengths))

【问题讨论】:

  • 基本 R 选项是 sapply(split(df$isFailure, df$customerId), function(x) {tmp &lt;- with(rle(x==1), lengths[values]); if(length(tmp)==0) 0 else tmp})
  • data.table 的另一个选项是 setDT(df)[, {tmp &lt;- rleid(isFailure)*isFailure; tmp2 &lt;- table(tmp[.N==1|tmp!=0]); max((names(tmp2)!=0)*tmp2)}, customerId][]

标签: r dplyr


【解决方案1】:

我们按“customerId”分组并使用do 在“isFailure”列上执行rle。为values (lengths[values]) 提取为“TRUE”的lengths,并使用if/else 条件创建“Max”列,以便为那些没有任何1 值的列返回0。

 df %>%
    group_by(customerId) %>%
    do({tmp <- with(rle(.$isFailure==1), lengths[values])
     data.frame(customerId= .$customerId, Max=if(length(tmp)==0) 0 
                    else max(tmp)) }) %>% 
     slice(1L)
#   customerId Max
#1          1   0
#2          2   1
#3          3   2

【讨论】:

    【解决方案2】:

    这是我的尝试,只使用标准的dplyr 函数:

    df %>% 
      # grouping key(s):
      group_by(customerId) %>%
      # check if there is any value change
      # if yes, a new sequence id is generated through cumsum
      mutate(last_one = lag(isFailure, 1, default = 100), 
             not_eq = last_one != isFailure, 
             seq = cumsum(not_eq)) %>% 
      # the following is just to find the largest sequence
      count(customerId, isFailure, seq) %>% 
      group_by(customerId, isFailure) %>% 
      summarise(max_consecutive_event = max(n))
    

    输出:

    # A tibble: 5 x 3
    # Groups:   customerId [3]
      customerId isFailure max_consecutive_event
           <dbl>     <dbl>                 <int>
    1          1         0                     1
    2          2         0                     1
    3          2         1                     1
    4          3         0                     1
    5          3         1                     2
    

    isFailure 值的最终过滤器将产生想要的结果(但需要添加回 0 失败计数客户)。

    该脚本可以采用isFailure 列的任何值并计算具有相同值的最大连续天数。

    【讨论】:

      猜你喜欢
      • 2017-02-26
      • 1970-01-01
      • 1970-01-01
      • 2014-10-30
      • 1970-01-01
      • 2020-12-02
      • 1970-01-01
      • 1970-01-01
      • 2017-09-14
      相关资源
      最近更新 更多