В пакете data.table есть две функции, которые были бы полезны для этого.
Наиболее простой из них, вероятно, является функция inrange
:
Использование inrange
для идентификации строк вbb, где либо начато, либо остановлено, находятся в любом интервале начала и конца строки в aa.
library(data.table)
setDT(bb)
bb[started %inrange% aa | stopped %inrange% aa]
# letters started stopped
# 1: a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 3: c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 4: c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 5: b 2019-05-02 07:45:11 2019-05-02 07:45:36
Чтобы получить желаемые значения, сгруппируйте их по буквам и верните количество вхождений:
bb[started %inrange% aa | stopped %inrange% aa, list(count = .N), by = letters]
# letters count
#1: a 2
#2: c 2
#3: b 1
Для этого также может использоваться функция foverlaps
;более гибкий, но немного более сложный:
Первый набор ключей для aa и bb:
setDT(aa)
setkey(aa, start, end)
setDT(bb)
setkey(bb, started, stopped)
Простой вызов foverlaps показывает результат объединения с NA для строк в bb, которыене сопоставлять интервалы в aa.
foverlaps(aa, bb)
# start end letters started stopped
# 1: 2019-05-02 07:29:23 2019-05-02 07:30:35 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: 2019-05-02 07:30:16 2019-05-02 07:30:53 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 3: <NA> <NA> a 2019-05-02 07:30:56 2019-05-02 07:31:29
# 4: <NA> <NA> b 2019-05-02 07:31:29 2019-05-02 07:31:55
# 5: <NA> <NA> d 2019-05-02 07:31:55 2019-05-02 07:32:22
# 6: <NA> <NA> b 2019-05-02 07:32:22 2019-05-02 07:32:48
# 7: 2019-05-02 07:33:13 2019-05-02 07:33:48 a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 8: 2019-05-02 07:33:13 2019-05-02 07:33:48 c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 9: 2019-05-02 07:43:26 2019-05-02 07:45:19 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 10: 2019-05-02 07:44:59 2019-05-02 07:45:35 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 11: 2019-05-02 07:43:26 2019-05-02 07:45:19 b 2019-05-02 07:45:11 2019-05-02 07:45:36
# 12: 2019-05-02 07:44:59 2019-05-02 07:45:35 b 2019-05-02 07:45:11 2019-05-02 07:45:36
# 13: <NA> <NA> c 2019-05-02 07:45:36 2019-05-02 07:46:01
# 14: <NA> <NA> a 2019-05-02 07:46:01 2019-05-02 07:46:25
# 15: <NA> <NA> c 2019-05-02 07:48:14 2019-05-02 07:48:48
Чтобы получить только те строки в bb, которые соответствуют интервалу в aa, используйте set nomatch
:
foverlaps(bb, aa, nomatch = NULL)
Аналогично, чтобы показатьДля каждой соответствующей строки только один раз установите mult
:
foverlaps(bb, aa, nomatch = NULL, mult = "first")
# start end letters started stopped
# 1: 2019-05-02 07:29:23 2019-05-02 07:30:35 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: 2019-05-02 07:33:13 2019-05-02 07:33:48 a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 3: 2019-05-02 07:33:13 2019-05-02 07:33:48 c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 4: 2019-05-02 07:43:26 2019-05-02 07:45:19 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 5: 2019-05-02 07:43:26 2019-05-02 07:45:19 b 2019-05-02 07:45:11 2019-05-02 07:45:36
И вы можете посчитать совпадающие вхождения каждой буквы, сгруппировавшись по буквам и посчитав строки:
foverlaps(aa, bb, nomatch = NULL, mult = "first")[ , list(count = .N), by = letters]
# letters count
#1: a 2
#2: c 2
#3: b 1