【问题标题】:Conditional stopping of mutate有条件地停止突变
【发布时间】:2021-03-12 17:53:50
【问题描述】:

我有一个数据集,我希望使用mutatecase_when。但是,我想在达到某个逻辑后停止/过滤变异。

数据:

set.seed(2020)
df <- tibble(
  customer = seq(1:5),
  start_date = sample(seq(as.Date('2020-01-01'),
                          as.Date('2020-12-31'),
                          by = "day"), 5),
  termination_date = c(sample(seq(as.Date('2020-06-01'),
                          as.Date('2021-02-28'),
                          by = "day"), 4), NA))

参数:

obs_start <- as.Date("2020-08-01")
obs_interval <- months(1)
lead_time <- weeks(1)

first_obs <- obs_start - lead_time
last_obs <- first_obs %m+% months(6)
obs_seq <- seq(first_obs, last_obs, by = "month")

mutate + case_when

df %>% 
  filter(termination_date > first_obs | is.na(termination_date)) %>% 
  crossing(obs_seq) %>% 
  mutate(is_churn = case_when(
    termination_date >= obs_seq &
      termination_date < (obs_seq + obs_interval) ~ "Yes",
    TRUE ~ "No"
  ))
   customer start_date termination_date obs_seq    is_churn
      <int> <date>     <date>           <date>     <chr>   
 1        1 2020-08-23 2021-02-28       2020-07-25 No      
 2        1 2020-08-23 2021-02-28       2020-08-25 No      
 3        1 2020-08-23 2021-02-28       2020-09-25 No      
 4        1 2020-08-23 2021-02-28       2020-10-25 No      
 5        1 2020-08-23 2021-02-28       2020-11-25 No      
 6        1 2020-08-23 2021-02-28       2020-12-25 No      
 7        1 2020-08-23 2021-02-28       2021-01-25 No      
 8        2 2020-03-27 2020-11-11       2020-07-25 No      
 9        2 2020-03-27 2020-11-11       2020-08-25 No      
10        2 2020-03-27 2020-11-11       2020-09-25 No      
11        2 2020-03-27 2020-11-11       2020-10-25 Yes     
12        2 2020-03-27 2020-11-11       2020-11-25 No      
13        2 2020-03-27 2020-11-11       2020-12-25 No      
14        2 2020-03-27 2020-11-11       2021-01-25 No      
15        3 2020-01-22 2020-11-17       2020-07-25 No      
16        3 2020-01-22 2020-11-17       2020-08-25 No      
17        3 2020-01-22 2020-11-17       2020-09-25 No      
18        3 2020-01-22 2020-11-17       2020-10-25 Yes     
19        3 2020-01-22 2020-11-17       2020-11-25 No      
20        3 2020-01-22 2020-11-17       2020-12-25 No      
21        3 2020-01-22 2020-11-17       2021-01-25 No      
22        4 2020-08-03 2020-12-15       2020-07-25 No      
23        4 2020-08-03 2020-12-15       2020-08-25 No      
24        4 2020-08-03 2020-12-15       2020-09-25 No      
25        4 2020-08-03 2020-12-15       2020-10-25 No      
26        4 2020-08-03 2020-12-15       2020-11-25 Yes     
27        4 2020-08-03 2020-12-15       2020-12-25 No      
28        4 2020-08-03 2020-12-15       2021-01-25 No      
29        5 2020-11-16 NA               2020-07-25 No      
30        5 2020-11-16 NA               2020-08-25 No      
31        5 2020-11-16 NA               2020-09-25 No      
32        5 2020-11-16 NA               2020-10-25 No      
33        5 2020-11-16 NA               2020-11-25 No      
34        5 2020-11-16 NA               2020-12-25 No      
35        5 2020-11-16 NA               2021-01-25 No  

customer 的每一组中,我想删除is_churn == "Yes" 之后的所有行 以下是所需的输出:

# A tibble: 27 x 5
   customer start_date termination_date obs_seq    is_churn
      <int> <chr>      <chr>            <chr>      <chr>   
 1        1 2020-08-23 2021-02-28       2020-07-25 No      
 2        1 2020-08-23 2021-02-28       2020-08-25 No      
 3        1 2020-08-23 2021-02-28       2020-09-25 No      
 4        1 2020-08-23 2021-02-28       2020-10-25 No      
 5        1 2020-08-23 2021-02-28       2020-11-25 No      
 6        1 2020-08-23 2021-02-28       2020-12-25 No      
 7        1 2020-08-23 2021-02-28       2021-01-25 No      
 8        2 2020-03-27 2020-11-11       2020-07-25 No      
 9        2 2020-03-27 2020-11-11       2020-08-25 No      
10        2 2020-03-27 2020-11-11       2020-09-25 No      
11        2 2020-03-27 2020-11-11       2020-10-25 Yes     
12        3 2020-01-22 2020-11-17       2020-07-25 No      
13        3 2020-01-22 2020-11-17       2020-08-25 No      
14        3 2020-01-22 2020-11-17       2020-09-25 No      
15        3 2020-01-22 2020-11-17       2020-10-25 Yes     
16        4 2020-08-03 2020-12-15       2020-07-25 No      
17        4 2020-08-03 2020-12-15       2020-08-25 No      
18        4 2020-08-03 2020-12-15       2020-09-25 No      
19        4 2020-08-03 2020-12-15       2020-10-25 No      
20        4 2020-08-03 2020-12-15       2020-11-25 Yes     
21        5 2020-11-16 NA               2020-07-25 No      
22        5 2020-11-16 NA               2020-08-25 No      
23        5 2020-11-16 NA               2020-09-25 No      
24        5 2020-11-16 NA               2020-10-25 No      
25        5 2020-11-16 NA               2020-11-25 No      
26        5 2020-11-16 NA               2020-12-25 No      
27        5 2020-11-16 NA               2021-01-25 No  

客户 1 不变,因为 termination_date 不属于观察期。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    每个customer 有条件的filter 行:

    library(dplyr)
    
    df %>% 
      filter(termination_date > first_obs | is.na(termination_date)) %>% 
      tidyr::crossing(obs_seq) %>% 
      mutate(is_churn = case_when(
        termination_date >= obs_seq &
          termination_date < (obs_seq + obs_interval) ~ "Yes",
        TRUE ~ "No"
      )) %>%
      group_by(customer) %>%
      filter(if(any(is_churn == 'Yes')) row_number() <= match('Yes', is_churn) else TRUE) %>%
      ungroup 
    
    #   customer start_date termination_date    obs_seq is_churn
    #1         1 2020-08-23       2021-02-28 2020-07-25       No
    #2         1 2020-08-23       2021-02-28 2020-08-25       No
    #3         1 2020-08-23       2021-02-28 2020-09-25       No
    #4         1 2020-08-23       2021-02-28 2020-10-25       No
    #5         1 2020-08-23       2021-02-28 2020-11-25       No
    #6         1 2020-08-23       2021-02-28 2020-12-25       No
    #7         1 2020-08-23       2021-02-28 2021-01-25       No
    #8         2 2020-03-27       2020-11-11 2020-07-25       No
    #9         2 2020-03-27       2020-11-11 2020-08-25       No
    #10        2 2020-03-27       2020-11-11 2020-09-25       No
    #11        2 2020-03-27       2020-11-11 2020-10-25      Yes
    #12        3 2020-01-22       2020-11-17 2020-07-25       No
    #13        3 2020-01-22       2020-11-17 2020-08-25       No
    #14        3 2020-01-22       2020-11-17 2020-09-25       No
    #15        3 2020-01-22       2020-11-17 2020-10-25      Yes
    #16        4 2020-08-03       2020-12-15 2020-07-25       No
    #17        4 2020-08-03       2020-12-15 2020-08-25       No
    #18        4 2020-08-03       2020-12-15 2020-09-25       No
    #19        4 2020-08-03       2020-12-15 2020-10-25       No
    #20        4 2020-08-03       2020-12-15 2020-11-25      Yes
    #21        5 2020-11-16             <NA> 2020-07-25       No
    #22        5 2020-11-16             <NA> 2020-08-25       No
    #23        5 2020-11-16             <NA> 2020-09-25       No
    #24        5 2020-11-16             <NA> 2020-10-25       No
    #25        5 2020-11-16             <NA> 2020-11-25       No
    #26        5 2020-11-16             <NA> 2020-12-25       No
    #27        5 2020-11-16             <NA> 2021-01-25       No 
    

    对于customer,如果churn 的任何值是'Yes',则选择包括其自身在内的所有行。如果没有churn = 'Yes',则选择所有行。

    【讨论】:

      猜你喜欢
      • 2017-09-29
      • 2021-02-27
      • 2020-04-01
      • 1970-01-01
      • 2017-10-04
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多