как установить POSIXct из диапазона POSIXct - PullRequest
0 голосов
/ 07 июня 2019

У меня проблема с выяснением того, как извлечь время событий, которые произошли в другое время события (в моем случае буквы). Я надеюсь, что кто-то может помочь мне! короче говоря: я хотел бы, чтобы строки bb tibble, чье время начала или окончания или оба (начало и конец) находились в диапазоне записей. Конечная цель состоит в том, чтобы найти, сколько раз буквы встречались в тибле. Пожалуйста, дайте мне знать, если нужны дополнительные разъяснения! Заранее спасибо!

aa <- tibble(
           start = as.POSIXct(c("2019-05-02 07:08:49", "2019-05-02 07:09:21",
                                    "2019-05-02 07:09:41", "2019-05-02 07:10:05",
                                    "2019-05-02 07:24:52", "2019-05-02 07:28:50",
                                    "2019-05-02 07:29:23", "2019-05-02 07:30:16",
                                    "2019-05-02 07:33:13", "2019-05-02 07:33:43",
                                    "2019-05-02 07:35:31", "2019-05-02 07:36:29",
                                    "2019-05-02 07:38:14", "2019-05-02 07:43:26",
                                    "2019-05-02 07:44:59", "2019-05-02 07:53:45",
                                    "2019-05-02 07:54:28")),
           end = as.POSIXct(c("2019-05-02 07:09:29", "2019-05-02 07:10:02",
                                    "2019-05-02 07:10:17", "2019-05-02 07:10:40",
                                    "2019-05-02 07:29:10", "2019-05-02 07:29:32",
                                    "2019-05-02 07:30:35", "2019-05-02 07:30:53",
                                    "2019-05-02 07:33:48", "2019-05-02 07:34:18",
                                    "2019-05-02 07:36:06", "2019-05-02 07:38:34",
                                    "2019-05-02 07:38:49", "2019-05-02 07:45:19",
                                    "2019-05-02 07:45:35", "2019-05-02 07:54:20",
                                    "2019-05-02 07:55:03")))

bb <- tibble(letters = sample(letters[1:4], 12, TRUE), 
             started = as.POSIXct(c("2019-05-02 07:30:23", "2019-05-02 07:30:56",
                                      "2019-05-02 07:31:29", "2019-05-02 07:31:55",
                                      "2019-05-02 07:32:22", "2019-05-02 07:32:48",
                                      "2019-05-02 07:33:14", "2019-05-02 07:44:36",
                                      "2019-05-02 07:45:11", "2019-05-02 07:45:36",
                                      "2019-05-02 07:46:01", "2019-05-02 07:48:14"
                                     )),
             stopped = as.POSIXct(c("2019-05-02 07:30:56", "2019-05-02 07:31:29",
                                    "2019-05-02 07:31:55", "2019-05-02 07:32:22",
                                    "2019-05-02 07:32:48", "2019-05-02 07:33:14",
                                    "2019-05-02 07:33:40", "2019-05-02 07:45:10",
                                    "2019-05-02 07:45:36", "2019-05-02 07:46:01",
                                    "2019-05-02 07:46:25", "2019-05-02 07:48:48")))

Ответы [ 2 ]

2 голосов
/ 07 июня 2019

Вот подход, использующий fuzzyjoin, который позволяет вам указать, что bb$started должно быть> = aa$start, а bb$stopped <= aa$end.

library(fuzzyjoin); 
fuzzy_inner_join(bb, aa,
                   by = c("started" = "start",
                          "stopped" = "end"),
                   match_fun = list(`>=`, `<=`)
                 )

# A tibble: 2 x 5
  letters started             stopped             start               end                
  <chr>   <dttm>              <dttm>              <dttm>              <dttm>             
1 a       2019-05-02 07:33:14 2019-05-02 07:33:40 2019-05-02 07:33:13 2019-05-02 07:33:48
2 c       2019-05-02 07:44:36 2019-05-02 07:45:10 2019-05-02 07:43:26 2019-05-02 07:45:19
1 голос
/ 08 июня 2019

В пакете 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
...