У меня есть фрейм данных с датами, которые я хотел бы сравнить с помощью group_by, но мне нужно сравнить их со ВСЕМИ другими датами в их группе, чтобы создать маршрут без пропусков или перекрытий, чтобы я мог получить только максимальное значениедата и минимальная дата начала для каждого идентификатора, воспроизводимый пример:
ID <- c(1,1,1,3,3,7,7,7,22,22,32,32,173,173,213,213,230,330,330,330,330,150579)
EndDate <- c("9999-12-31","2018-04-30","2015-07-31","9999-12-31","2008-07-26","9999-12-31","9999-12-31","2011-08-31","9999-12-31","2006-11-30","9999-12-31","2007-06-30","9999-12-31","2010-09-30","9999-12-31","2013-04-30","9999-12-31","9999-12-31","2016-12-31","2016-09-30","2015-08-31","9999-12-31")
BegDate <- c("2015-08-01","2017-10-23","1983-12-05","2015-11-12","2003-02-24","2017-04-01","2014-07-15","1991-11-04","2006-12-01","1979-08-01","2007-07-01","1979-08-01","2010-10-01","1987-04-01","1980-10-20","2008-05-01","1983-02-14","1982-01-01","2016-10-01","2015-09-01","2014-02-01","1982-09-01")
df_dates <- data.frame(ID,EndDate,BegDate)
ID EndDate BegDate
1 9999-12-31 2015-08-01
1 2018-04-30 2017-10-23
1 2015-07-31 1983-12-05
3 9999-12-31 2015-11-12
3 9999-12-31 2015-11-12
7 9999-12-31 2017-04-01
7 9999-12-31 2014-07-15
7 2011-08-31 1991-11-04
22 9999-12-31 2006-12-01
22 2006-11-30 1979-08-01
32 9999-12-31 2007-07-01
32 2007-06-30 1979-08-01
173 9999-12-31 2010-10-01
173 2010-09-30 1987-04-01
213 9999-12-31 1980-10-20
213 2013-04-30 2008-05-01
233 9999-12-31 2016-06-01
233 2016-05-31 1998-10-01
330 9999-12-31 1982-01-01
330 2016-12-31 2016-10-01
330 2016-09-30 2015-09-01
330 2015-08-31 2014-02-01
150579 9999-12-31 1982-09-01
Я пробовал dplyr, но не знаю, как сделать сравнение между ВСЕМИ элементами группы.Я использовал цикл for, но фрейм данных огромен, и скорость необходима.
v_result <- c()
for(i in unique(df_dates$ID)){
df_temp <- df_dates[df_dates$ID == i,]
df_temp$EndDate <- as.Date(df_temp$EndDate,"%Y%m%d")
df_temp$BegDate <- as.Date(df_temp$BegDate,"%Y%m%d")
v_row <- (1:nrow(df_temp))
for (j in v_row){
h = j + 1
elm <- v_row[!v_row %in% j]
findNext <- FALSE
for(h in elm){
if((df_temp$EndDate[j] >= df_temp$EndDate[h] AND
df_temp$BegDate[j] <= df_temp$BegDate[h]) |
df_temp$BegDate[j] - days(1) == df_temp$EndDate[h]){
findNext <- TRUE
}
}
v_result <- c(v_result,findNext)
}
}
Как вы можете видеть, много циклов for, и я не понимаю семейство функций apply
очень хорошо, плюс, вероятно, есть более 150 тыс. идентификаторов, так что это нереальный вариант.Моя идея состояла в том, чтобы пометить как ложные перекрывающиеся и те, которые представляют пробел, и отфильтровать их, что позволило мне взять максимум и минимум
df_final <- df_final%>%
group_by(ID)%>%
mutate(
Biggest = max(EndDate),
Lowest = min(BegDate)
)
, генерируя что-то вроде этого:
ID EndDate BegDate
1 9999-12-31 1983-12-05
3 9999-12-31 2015-11-12
7 9999-12-31 2014-07-15
22 9999-12-31 1979-08-01
32 9999-12-31 1979-08-01
173 9999-12-31 2017-07-01
213 9999-12-31 1980-10-20
233 9999-12-31 1998-10-01
330 9999-12-31 1982-01-01
150579 9999-12-31 1982-09-01
Дата окончания не всегда может быть 9999-12-31, поскольку это самая большая дата по идентификатору, соответствующая периоду без пропусков и игнорирующим перекрытия.Я боролся с этим уже несколько дней и не могу добиться прогресса.
Есть ли способ сделать это с помощью dplyr, который эффективен для больших фреймов данных?