1) sqldf Предполагая, что вы хотите перекрывать только время, а не даты, замените inter1
на start
, end
, а также время начала и окончания, time1
и time2
, давая new_df1
. Затем выполните самообъединение на id
и группировку условий перекрытия по rowid
. overlap
ИСТИНА, если число совпадающих строк превышает 1 (поскольку само перекрытие не учитывается).
library(dplyr)
library(lubridate)
library(sqldf)
new_df1 <- new_df %>%
mutate(
start = int_start(inter1),
end = int_end(inter1),
time1 = sub(".* ", "", start),
time2 = sub(".* ", "", end),
inter1 = NULL
)
sqldf("select a.id, a.start, a.end, count(*) > 1 as overlap
from new_df1 a
join new_df1 b on a.id = b.id and
(a.time1 between b.time1 and b.time2 or b.time1 between a.time1 and a.time2)
group by a.rowid")
, что дает:
id start end overlap
1 1 2017-06-27 05:30:00 2017-06-27 06:30:00 FALSE
2 1 2017-06-27 11:30:00 2017-06-27 13:30:00 TRUE
3 1 2017-06-28 10:30:00 2017-06-28 14:30:00 TRUE
4 2 2017-06-28 05:30:00 2017-06-28 06:30:00 FALSE
5 2 2017-06-28 11:00:00 2017-06-28 12:00:00 FALSE
2) Это формирует полное соединение ni x ni для каждого идентификатора i, а затем отфильтровывает его и группирует как второй и третий этап, тогда как (1) делает все это одновременно, в зависимости от SQL оптимизаций, применяемых программным обеспечением базы данных (1 ) может быть гораздо более эффективным. В любом случае, это включается в id
, а затем фильтрует условие перекрытия и, наконец, выполняет подсчет. new_df1
от (1).
new_df1 %>%
mutate(rowid = 1:n()) %>%
inner_join(new_df1, by = "id", suffix = c("", ".y")) %>%
filter((time1 >= time1.y & time1 <= time2.y) |
(time1.y >= time1 & time1.y <= time2)) %>%
count(rowid, id, start, end) %>%
mutate(overlap = n > 1) %>%
select(id, start, end, overlap)
давая:
# A tibble: 5 x 4
rowid start end overlap
<int> <dttm> <dttm> <lgl>
1 1 2017-06-27 09:30:00 2017-06-27 10:30:00 FALSE
2 2 2017-06-27 15:30:00 2017-06-27 17:30:00 TRUE
3 3 2017-06-28 14:30:00 2017-06-28 18:30:00 TRUE
4 4 2017-06-28 09:30:00 2017-06-28 10:30:00 FALSE
5 5 2017-06-28 15:00:00 2017-06-28 16:00:00 FALSE
Примечание
Постер изменил вопрос после того, как на него уже был дан ответ, но в любом случае мы использовали это в качестве ввода.
new_df <-
structure(list(id = c(1, 1, 1, 2, 2), inter1 = new("Interval",
.Data = c(3600, 7200, 14400, 3600, 3600), start = structure(c(1498555800,
1498577400, 1498660200, 1498642200, 1498662000), tzone = "UTC",
class = c("POSIXct",
"POSIXt")), tzone = "UTC"), overlap = c(FALSE, TRUE, TRUE,
FALSE, FALSE)), class = "data.frame", row.names = c(NA, -5L))