Как я могу создать группирующую переменную, отмечающую непрерывные поездки? - PullRequest
2 голосов
/ 25 апреля 2019

У меня есть список путешествий, которые мне нужно сгруппировать по определенным критериям.

Ship| From     |  To      | Departure_From  | Departure_To
   1| HAMBURG  | SETUBAL  | 16-09-2018 22:12| 08-10-2018 13:42
   1| SETUBAL  | NAPOLI   | 08-10-2018 13:42| 16-10-2018 00:18
   2| HAMBURG  | SETUBAL  | 14-10-2018 18:30| 07-11-2018 13:55
   2| SETUBAL  | HAMBURG  | 07-11-2018 13:55| 20-11-2018 13:16
   3| JEDDAH   | ALGECIRAS| 10-05-2018 21:46| 30-05-2018 17:20
   3| ALGECIRAS| TANGIER  | 30-05-2018 17:20| 31-05-2018 08:41
   3| TANGIER  | ALGECIRAS| 05-09-2018 21:34| 13-09-2018 22:22
   3| ALGECIRAS| TANGIER  | 13-09-2018 22:22| 15-09-2018 08:40
   4| FOS      | ALGECIRAS| 05-09-2018 11:02| 07-09-2018 20:18
   4| ALGECIRAS| Baltiysk | 07-09-2018 20:18| 15-09-2018 05:28
   4| Baltiysk | GDANSK   | 15-09-2018 05:28| 16-09-2018 14:34

Столбец судна содержит номер судна, столбцы From и To - это имена портов, Departure_From - вылет из порта «From», а Departure_To - вылет из порта «To». Мне нужно сгруппировать этот конкретный набор данных следующим образом: Обратите внимание, что если это непрерывный рейс, то дата Departure_To будет такой же, как дата Departure_From следующей записи, как и порт. Если это другое, то это другое путешествие.

  1. Корабль № 1 отправляется из Гамбурга и идет в Сетубал, а в следующем рейсе отправляется из Сетубала и идет в Неаполь. Обратите внимание, что дата Departure_To первой записи совпадает с датой Departure_From следующей записи, так же как и порт. Следовательно, это одно непрерывное путешествие. Я хотел бы объединить это в единый рейс, который идет из Гамбурга (первый порт) в Неаполь (последний порт), и в поле Departure_From должна быть дата отправления Гамбург, а Departure_To - дата отправления из Неаполя.
  2. Для корабля нет. 3, есть два рейса. Первый рейс из Джидды в Альхесирас и Альхесирас в Танжер (это одно непрерывное путешествие), а второй рейс из Танжера в Альхесирас и Альхесирас обратно в Танжер. Таким образом, в этом случае должно быть две группы: одна от Джидды до Танжера и вторая от Танжера до Танжера.
  3. Случай с кораблем № 4 немного сложнее, так как корабль начинается с Фоса и идет в Альхесирас, затем из Альхесираса в Балтийск и, наконец, из Балтийска в ГДАНЬСК. В этом случае 3 рейса должны быть объединены в один (так как это непрерывный рейс - на дату совпадает с датой следующей записи), то есть от Fos до GDANSK.

Я хочу, чтобы конечный результат выглядел следующим образом.

Ship| From     |  To      | Departure_From  | Departure_To
   1| HAMBURG  | NAPOLI   | 16-09-2018 22:12| 16-10-2018 00:18
   2| HAMBURG  | HAMBURG  | 14-10-2018 18:30| 20-11-2018 13:16
   3| JEDDAH   | TANGIER  | 10-05-2018 21:46| 31-05-2018 08:41
   3| TANGIER  | TANGIER  | 05-09-2018 21:34| 15-09-2018 08:40
   4| FOS      | GDANSK   | 05-09-2018 11:02| 16-09-2018 14:34

Код для создания вышеуказанного набора данных.

data.frame(Ship= c(1,1,2,2,3,3,3,3,4,4,4), 
           From=c("HAMBURG","SETUBAL","HAMBURG","SETUBAL","JEDDAH","ALGECIRAS","TANGIER","ALGECIRAS","FOS SUR MER","ALGECIRAS","Baltiysk"), 
           To= c("SETUBAL","NAPOLI","SETUBAL","HAMBURG","ALGECIRAS","TANGIER","ALGECIRAS","TANGIER","ALGECIRAS","Baltiysk","GDANSK"), 
           Departure_From= c("16-09-2018  22:12:00",
                "08-10-2018  13:42:00",
                "14-10-2018  18:30:00",
                "07-11-2018  13:55:00",
                "10-05-2018  21:46:00",
                "30-05-2018  17:20:00",
                "05-09-2018  21:34:00",
                "13-09-2018  22:22:00",
                "05-09-2018  11:02:00",
                "07-09-2018  20:18:00",
                "15-09-2018  05:28:00"), 
           Departure_To= c("08-10-2018  13:42:00",
               "16-10-2018  00:18:00",
               "07-11-2018  13:55:00",
               "20-11-2018  13:16:00",
               "30-05-2018  17:20:00",
               "31-05-2018  08:41:00",
               "13-09-2018  22:22:00",
               "15-09-2018  08:40:00",
               "07-09-2018  20:18:00",
               "15-09-2018  05:28:00",
               "16-09-2018  14:34:00"
))

Любая помощь будет принята с благодарностью. (Предпочел бы сделать это в Tidyverse, так как мне это удобно)

1 Ответ

3 голосов
/ 25 апреля 2019

Хитрость в создании идентификаторов группировки заключается в том, чтобы использовать cumsum с dplyr::lag (или lead) и выяснить, как сделать только те строки, для которых новая группа должна начинаться с оценки TRUE. Здесь мы хотим отметить новую поездку, если она имеет Departure_From, отличное от Departure_To в предыдущем ряду. Если это первая строка для этого корабля, она автоматически изменится, потому что мы установили default = "".

После того, как у нас есть номер рейса для каждого корабля, можно просто summarise получить первое и последнее значения для каждой поездки соответственно. Обратите внимание, что предоставленные вами данные вызывают город FOS SUR MER.

library(tidyverse)
tbl <- tibble(Ship = c(1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4), From = c("HAMBURG", "SETUBAL", "HAMBURG", "SETUBAL", "JEDDAH", "ALGECIRAS", "TANGIER", "ALGECIRAS", "FOS SUR MER", "ALGECIRAS", "Baltiysk"), To = c("SETUBAL", "NAPOLI", "SETUBAL", "HAMBURG", "ALGECIRAS", "TANGIER", "ALGECIRAS", "TANGIER", "ALGECIRAS", "Baltiysk", "GDANSK"), Departure_From = c("16-09-2018  22:12:00", "08-10-2018  13:42:00", "14-10-2018  18:30:00", "07-11-2018  13:55:00", "10-05-2018  21:46:00", "30-05-2018  17:20:00", "05-09-2018  21:34:00", "13-09-2018  22:22:00", "05-09-2018  11:02:00", "07-09-2018  20:18:00", "15-09-2018  05:28:00"), Departure_To = c("08-10-2018  13:42:00", "16-10-2018  00:18:00", "07-11-2018  13:55:00", "20-11-2018  13:16:00", "30-05-2018  17:20:00", "31-05-2018  08:41:00", "13-09-2018  22:22:00", "15-09-2018  08:40:00", "07-09-2018  20:18:00", "15-09-2018  05:28:00", "16-09-2018  14:34:00"))
tbl %>%
  group_by(Ship) %>%
  mutate(trip_num = cumsum(Departure_From != lag(Departure_To, default = ""))) %>%
  group_by(Ship, trip_num) %>%
  summarise(
    From = first(From),
    To = last(To),
    Departure_From = first(Departure_From),
    Departure_To = last(Departure_To)
  )
#> # A tibble: 5 x 6
#> # Groups:   Ship [4]
#>    Ship trip_num From        To      Departure_From      Departure_To      
#>   <dbl>    <int> <chr>       <chr>   <chr>               <chr>             
#> 1     1        1 HAMBURG     NAPOLI  16-09-2018  22:12:… 16-10-2018  00:18…
#> 2     2        1 HAMBURG     HAMBURG 14-10-2018  18:30:… 20-11-2018  13:16…
#> 3     3        1 JEDDAH      TANGIER 10-05-2018  21:46:… 31-05-2018  08:41…
#> 4     3        2 TANGIER     TANGIER 05-09-2018  21:34:… 15-09-2018  08:40…
#> 5     4        1 FOS SUR MER GDANSK  05-09-2018  11:02:… 16-09-2018  14:34…

Создано в 2019-04-25 пакетом представ. (v0.2.1)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...