按日期集对数据分组

时间:2020-09-30 07:27:09

标签: r date data.table

我有一个数据集,用于查看一段时间内的交易,我正在尝试为每个ID识别交易时间。数据的基本示例如下所示。

# id       date
# 1  2018-02-01
# 1  2018-03-01
# 1  2018-04-01
# 1  2018-05-01
# 1  2018-06-01
# 1  2018-06-01
# 2  2018-02-01
# 2  2018-03-01
# 2  2018-05-01
# 2  2019-01-01
# 2  2019-02-01
# 2  2020-06-12
# 2  2020-07-13
# 2  2020-08-11

我想要做的是根据先前记录日期的临近程度对数据进行分组。因此,如果id的间隔不超过3个月,他们将获得相同的组号。我整理了一个示例,说明预期的结果是什么样的。

# id       date group
# 1  2018-02-01     1
# 1  2018-03-01     1
# 1  2018-04-01     1
# 1  2018-05-01     1
# 1  2018-06-01     1
# 1  2018-06-01     1
# 2  2018-02-01     1
# 2  2018-03-01     1
# 2  2018-05-01     1
# 2  2019-01-01     2
# 2  2019-02-01     2
# 2  2020-06-12     3
# 2  2020-07-13     3
# 2  2020-08-11     3

因此,我试图考虑使用rleid()或使用shift()来解决问题的方法,但是无法为此找到合适的解决方案。我确实想知道其中的某些原因是否归因于缺乏R词汇,所以任何想法都将不胜感激。

2 个答案:

答案 0 :(得分:2)

当当前日期比上一个日期大3个月时,您可以在每个group中增加id的值。

library(dplyr)
library(lubridate)

df %>%
    group_by(id) %>%
    mutate(group = cumsum((date %m-% months(3)) > 
                           lag(date, default = first(date))) + 1)

#      id date       group
#   <int> <date>     <dbl>
# 1     1 2018-02-01     1
# 2     1 2018-03-01     1
# 3     1 2018-04-01     1
# 4     1 2018-05-01     1
# 5     1 2018-06-01     1
# 6     1 2018-06-01     1
# 7     2 2018-02-01     1
# 8     2 2018-03-01     1
# 9     2 2018-05-01     1
#10     2 2019-01-01     2
#11     2 2019-02-01     2
#12     2 2020-06-12     3
#13     2 2020-07-13     3
#14     2 2020-08-11     3

data.table中:

library(data.table)
setDT(df)[, group := cumsum((date %m-% months(3)) > 
                             shift(date, fill = first(date))) + 1, id]

数据

df <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L), date = structure(c(17563, 17591, 17622, 17652, 
17683, 17683, 17563, 17591, 17652, 17897, 17928, 18425, 18456, 
18485), class = "Date")), row.names = c(NA, -14L), class = "data.frame")

答案 1 :(得分:0)

使用ave + cumsum + diff

的基本R选项
within(
  df,
  group <- ave(as.numeric(date), id, FUN = function(x) cumsum(c(0, diff(x) > 30.42 * 3)) + 1)
)

给出

   id       date group
1   1 2018-02-01     1
2   1 2018-03-01     1
3   1 2018-04-01     1
4   1 2018-05-01     1
5   1 2018-06-01     1
6   1 2018-06-01     1
7   2 2018-02-01     1
8   2 2018-03-01     1
9   2 2018-05-01     1
10  2 2019-01-01     2
11  2 2019-02-01     2
12  2 2020-06-12     3
13  2 2020-07-13     3
14  2 2020-08-11     3