下面是我遇到的问题的一个例子。具体来说,我遇到的情况是,连续日期条目的人员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
你可以用这样的方式对行号做一些技巧:
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
这将计算行号的"天"与日期之间的差异,只要差异保持不变,它就是连续日期。
这是一个冗长的解决方案。首先,我检测连续的组并将其存储在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