计算每组连续的先前日期

时间:2020-03-04 14:11:21

标签: r dataframe dplyr

我的示例data.frame(日期格式为d / m / y),记录了客户活动的日期:

customer    date 
1           10/1/20
1           9/1/20 
1           6/1/20
2           10/1/20
2           8/1/20
2           7/1/20
2           6/1/20

我想像这样创建一列“ n_consecutive_days”:

customer    date    n_consecutive_days
1           10/1/20  2
1           9/1/20   1
1           6/1/20   N/A
2           10/1/20  1
2           8/1/20   3
2           7/1/20   2
2           6/1/20   N/A

新列计算每个客户以前的连续日期数。我希望客户的第一个约会为N / A,因为如果是第一个约会,那么谈论前几天是没有意义的。

任何帮助将不胜感激。我可以计算日期之间的差,但不能计算所需的连续天数。

2 个答案:

答案 0 :(得分:2)

一种方法是:

library(dplyr)

df %>%
  group_by(customer, idx = cumsum(as.integer(c(0, diff(as.Date(date, '%d/%m/%y')))) != -1)) %>%
  mutate(n_consecutive_days = rev(sequence(n()))) %>% ungroup() %>%
  group_by(customer) %>%
  mutate(n_consecutive_days = replace(n_consecutive_days, row_number() == n(), NA), idx = NULL)

输出:

# A tibble: 7 x 3
# Groups:   customer [2]
  customer date    n_consecutive_days
     <int> <fct>                <int>
1        1 10/1/20                  2
2        1 9/1/20                   1
3        1 6/1/20                  NA
4        2 10/1/20                  1
5        2 8/1/20                   3
6        2 7/1/20                   2
7        2 6/1/20                  NA

答案 1 :(得分:1)

使用data.table的选项:

#ensure that data is sorted by customer and reverse chronological
setorder(DT, customer, -date)

#group by customer and consecutive dates and then create the sequence
DT[, ncd := .N:1L, .(customer, cumsum(c(0L, diff(date)!=-1L)))]

#set the first date in each customer to NA
DT[DT[, .I[.N], customer]$V1, ncd := NA]

输出:

   customer       date ncd
1:        1 2020-01-10   2
2:        1 2020-01-09   1
3:        1 2020-01-06  NA
4:        2 2020-01-10   1
5:        2 2020-01-08   3
6:        2 2020-01-07   2
7:        2 2020-01-06  NA

数据:

library(data.table)
DT <- fread("customer    date 
1           10/1/20
1           9/1/20 
1           6/1/20
2           10/1/20
2           8/1/20
2           7/1/20
2           6/1/20")
DT[, date := as.IDate(date, format="%d/%m/%y")]