Здесь мы предполагаем, что то, что запрашивается, находится в каждой смежной группе Person_ID и Departmwent, мы хотим установить минимальную и максимальную дату.
1) data.table Сначала преобразуйте Date
столбец к Date
классу и затем группировка по rleid(Person_ID)
принимает минимальное и максимальное значения.
library(data.table)
library(lubridate)
DT <- as.data.table(DF0)
DT[, Date := mdy(Date)][
, list(start = min(Date), end = max(Date)),
by = .(rleid(Person_ID, Department), Person_ID, Department)][-1]
, давая:
Person_ID Department start end
1: 351581 GH 2019-12-01 2019-12-03
2: 351581 FR 2019-12-02 2019-12-02
3: 598168 GH 2019-12-16 2019-12-16
4: 351581 JE 2019-12-08 2019-12-09
5: 615418 AB 2019-12-20 2019-12-20
2) База R Преобразуйте класс Date
в Date
, а затем создайте переменную группировки g
, используя rle
. Затем определите функцию Range
, которая выводит start
и end
для данной группы, и примените ее к каждой группе.
DF <- transform(DF0, Date = as.Date(Date, "%m/%d/%Y"))
g <- with(rle(paste(DF$Person_ID, DF$Department)), rep(seq_along(lengths), lengths))
Range <- function(x) data.frame(x[1, 1:2], start = min(x$Date), end = max(x$Date))
do.call("rbind", by(DF, g, Range))
, давая:
Person_ID Department start end
1 351581 GH 2019-12-01 2019-12-03
2 351581 FR 2019-12-02 2019-12-02
3 598168 GH 2019-12-16 2019-12-16
4 351581 JE 2019-12-08 2019-12-09
5 615418 AB 2019-12-20 2019-12-20
3) dplyr / data.table Смешанный подход, в котором мы используем rleid
из data.table и в противном случае используем dplyr, заключается в следующем. Преобразуйте дату, используя lubridate, и группу, используя rleid, Person_ID и Department. Последние два должны гарантировать, что они включены в вывод. Вычислите начало и конец, а затем удалите столбец группировки.
library(dplyr)
library(data.table)
library(lubridate)
DF0 %>%
mutate(Date = mdy(Date)) %>%
group_by(g = rleid(Person_ID, Department), Person_ID, Department) %>%
summarize(start = min(Date), end = max(Date)) %>%
ungroup %>%
select(-g)
, давая:
# A tibble: 5 x 4
Person_ID Department start end
<int> <fct> <date> <date>
1 351581 GH 2019-12-01 2019-12-03
2 351581 FR 2019-12-02 2019-12-02
3 598168 GH 2019-12-16 2019-12-16
4 351581 JE 2019-12-08 2019-12-09
5 615418 AB 2019-12-20 2019-12-20
4) sqldf Определите группу Grp
во внутренней выберите, а затем найдите минимальную и максимальную дату по Grp
.
library(sqldf)
DF <- trnsform(DF0, Date = as.Date(Date, "%m/%d/%Y"))
sqldf("select Person_ID, Department, min(Date) as start__Date, max(Date) as end__Date
from ( select
rowid r,
Person_ID,
Department,
Date,
Date - dense_rank() over (partition by Person_ID, Department order by rowid) as Grp
from DF
) group by Grp order by r", method = "name__class")
давая:
Person_ID Department start end
1 351581 GH 2019-12-01 2019-12-03
2 351581 FR 2019-12-02 2019-12-02
3 598168 GH 2019-12-16 2019-12-16
4 351581 JE 2019-12-08 2019-12-09
5 615418 AB 2019-12-20 2019-12-20
Примечание
Предполагается, что входное значение будет:
Lines <- "Person_ID Department Date
351581 GH 12/1/2019
351581 GH 12/2/2019
351581 GH 12/3/2019
351581 FR 12/2/2019
598168 GH 12/16/2019
351581 JE 12/8/2019
351581 JE 12/9/2019
615418 AB 12/20/2019"
DF0 <- read.table(text = Lines, header = TRUE)