将多次出现的ID的连续日期分组为个人遭遇

时间:2018-04-19 19:09:06

标签: r sql-server gaps-and-islands

以下是我遇到的问题的一个例子。具体来说,我的情况是连续日期条目的人员ID有多个条目。我想将这些连续的条目分组以显示特定的剧集。'

我有一张这样的表:

ID    DATE
A     11/16/2017
A     11/17/2017
A     11/18/2017
A     11/18/2017
B     11/12/2017
B     11/13/2017
B     11/14/2017
C     10/31/2017
C     10/31/2017
A     11/22/2017
A     11/22/2017
A     11/23/2017

我希望结果表在这个示例表

中是这样的
ID StartDATE  EndDATE
A    11/16/2017  11/18/2017
B    11/12/2017  11/14/2017
C    10/31/2017  10/31/2017
A    11/22/2017  11/23/2017

2 个答案:

答案 0 :(得分:1)

您可以使用以下内容对行号进行欺骗:

select ID, min(DATE), max(DATE) from
(
  select *, datediff(day, RN, DATE) GRP
  from (
    select *, row_number () over (partition by ID order by DATE asc) as RN
    from (
      select distinct ID, DATE from Table1
    ) X
  ) Y
) Z
group by ID, GRP

计算行号的“天”与日期之间的差异,只要差异保持不变,就是连续日期。

答案 1 :(得分:0)

这是一个冗长的解决方案。首先,我检测连续的组并将其存储在grp变量中。然后,我按ID分割数据,然后将范围函数应用于每个子集,并通过创建一个包含ID和两个日期的data.frame来使其变得漂亮。最后,do.call函数将所有内容粘合在一起。

xy <- read.table(text = "ID    DATE
A     11/16/2017
                 A     11/17/2017
                 A     11/18/2017
                 A     11/18/2017
                 B     11/12/2017
                 B     11/13/2017
                 B     11/14/2017
                 C     10/31/2017
                 C     10/31/2017
                 A     11/22/2017
                 A     11/22/2017
                 A     11/23/2017", header = TRUE)
xy$DATE <- as.Date(xy$DATE, format = "%m/%d/%Y")
xy$grp <- cumsum(c(1, diff(as.numeric(as.factor(xy$ID))) != 0))

split.by.id <- split(xy, f = xy$grp)
run.by.id <- lapply(split.by.id, FUN = function(x) {
  rng <- range(x$DATE)
  data.frame(ID = unique(x$ID), StartDate = rng[1], EndDate = rng[2])
})
range.by.id <- do.call(rbind, run.by.id)
range.by.id

  ID  StartDate    EndDate
1  A 2017-11-16 2017-11-18
2  B 2017-11-12 2017-11-14
3  C 2017-10-31 2017-10-31
4  A 2017-11-22 2017-11-23