Как сгруппировать данные из нескольких фреймов - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть 4 фрейма данных.

фрейм данных: адрес получения

ID    x1     x2      x3       x4         x5    x6.....x1090
1001  Place1 Place2  NA       NA         NA    NA
1002  Place1 Place2  Place 3  Place4     NA    NA
1003  Place5 Place3  Place 2  Place 2    NA    NA
1004  Place6 Place7  NA       NA         NA    NA 

фрейм данных: адрес возврата

ID    x1     x2      x3       x4         x5    x6.....x1090
1001  Place2 Place1  NA       NA         NA    NA
1002  Place2 Place1  Place4   Place3     NA    NA
1003  Place3 Place5  Place6   Place7     NA    NA
1004  Place7 Place6  NA       NA         NA    NA 

фрейм данных: даты

ID    x1         x2         x3        x4         x5    x6.....x1090
1001  4/1/2020   4/1/2020   NA        NA         NA    NA
1002  4/1/2020   4/1/2020   4/3/2020  4/3/2020   NA    NA
1003  4/3/2020   4/3/2020   4/4/2020  4/5/2020   NA    NA
1004  4/5/2020   4/5/2020   NA        NA         NA    NA 

dataframe: Time

    ID    x1           x2           x3            x4           x5    x6.....x1090
    1001  8:00:00 AM   4:00:00 PM   NA            NA           NA    NA
    1002  9:00:05 AM  12:35:05 PM   11:00:00 AM   4:00:00 AM   NA    NA
    1003  3:00:00 PM   6:00:00 PM   7:00:00 AM    3:00:00 PM   NA    NA
    1004  7:00:00 AM   3:00:00 PM   NA            NA           NA    NA 

Я хочу сгруппировать эти поездки по дате и найти цепочку поездок. Вывод будет примерно таким:

ID    Date      Tripchain                      Time                 
1001  4/1/2020  place 1- place 2- place 1      Morning- Afternoon
1002  4/1/2020  place 1- place 2- place 1      Morning -Afternoon
1002  4/3/2020  place 3- place 4- place 3      Morning -Afternoon
1003  4/3/2020  place 5- place 3- place 5      Afternoon-Afternoon
1003  4/4/2020  place 2- place 7               Morning
1003  4/5/2020  place 2- place 7               Afternoon
1004  4/5/2020  place 6- place 7- place 6      Morning-Afternoon

1 Ответ

0 голосов
/ 28 апреля 2020

Во-первых, я думаю, что ваш формат свертывания place1-place2-... внутри строки будет ужасно масштабироваться. Если это только для отчетов (никогда с использованием этих данных в этом формате), тогда все в порядке, но в противном случае я предлагаю вам разделить их.

Первое, что нужно сделать здесь, - это преобразовать отдельные кадры в комбинированный длинный формат. Я go чуть дальше и конвертирую даты / время в R-native POSIXt объекты:

dat <- list(
  pivot_longer(pickup, -ID, names_to = "x", values_to = "pickup"),
  pivot_longer(dropoff, -ID, names_to = "x", values_to = "dropoff"),
  pivot_longer(dates, -ID, names_to = "x", values_to = "date"),
  pivot_longer(times, -ID, names_to = "x", values_to = "time")
) %>%
  Reduce(function(a, b) full_join(a, b, by = c("ID", "x")), .) %>%
  filter(complete.cases(.)) %>%
  mutate(
    timestamp = as.POSIXct(paste(date, time), format = "%m/%d/%Y %I:%M:%S_%p"),
    date = as.Date(timestamp)
  ) %>%
  select(-x, -time)
dat
# # A tibble: 12 x 5
#       ID pickup dropoff date       timestamp              
#    <int> <chr>  <chr>   <date>     <dttm>                 
#  1  1001 Place1 Place2  2020-04-01 2020-04-01 08:00:00.000
#  2  1001 Place2 Place1  2020-04-01 2020-04-01 16:00:00.000
#  3  1002 Place1 Place2  2020-04-01 2020-04-01 09:00:05.000
#  4  1002 Place2 Place1  2020-04-01 2020-04-01 12:35:05.000
#  5  1002 Place3 Place4  2020-04-03 2020-04-03 11:00:00.000
#  6  1002 Place4 Place3  2020-04-03 2020-04-03 04:00:00.000
#  7  1003 Place5 Place3  2020-04-03 2020-04-03 15:00:00.000
#  8  1003 Place3 Place5  2020-04-04 2020-04-03 18:00:00.000
#  9  1003 Place2 Place6  2020-04-04 2020-04-04 07:00:00.000
# 10  1003 Place2 Place7  2020-04-05 2020-04-05 15:00:00.000
# 11  1004 Place6 Place7  2020-04-05 2020-04-05 07:00:00.000
# 12  1004 Place7 Place6  2020-04-05 2020-04-05 15:00:00.000

Отсюда, чтобы добраться туда, куда вы хотите go, я думаю, что мы можете упорядочить их (по отметке времени), сгруппировать их (по идентификатору), а затем объединить. Да, и конвертируйте в удобочитаемое «время суток».

time2human <- function(x) {
  as.character(
    cut(as.numeric(format(x, format = "%H")), c(-1, 4, 12, 17, 20, 25),
        labels = c("Night", "Morning", "Afternoon", "Evening", "Night"))
  )
}

dat %>%
  arrange(timestamp) %>%
  group_by(ID, date) %>%
  summarize(
    Tripchain = paste(c(pickup, last(dropoff)), collapse = " - "),
    Timeframe = paste(time2human(min(timestamp)), time2human(max(timestamp)),
                      sep = " - "),
    Time1 = first(timestamp), Time2 = last(timestamp)
  ) %>%
  ungroup()
# # A tibble: 7 x 6
#      ID date       Tripchain                Timeframe             Time1                   Time2                  
#   <int> <date>     <chr>                    <chr>                 <dttm>                  <dttm>                 
# 1  1001 2020-04-01 Place1 - Place2 - Place1 Morning - Afternoon   2020-04-01 08:00:00.000 2020-04-01 16:00:00.000
# 2  1002 2020-04-01 Place1 - Place2 - Place1 Morning - Morning     2020-04-01 09:00:05.000 2020-04-01 12:35:05.000
# 3  1002 2020-04-03 Place4 - Place3 - Place4 Night - Morning       2020-04-03 04:00:00.000 2020-04-03 11:00:00.000
# 4  1003 2020-04-03 Place5 - Place3          Afternoon - Afternoon 2020-04-03 15:00:00.000 2020-04-03 15:00:00.000
# 5  1003 2020-04-04 Place3 - Place2 - Place6 Evening - Morning     2020-04-03 18:00:00.000 2020-04-04 07:00:00.000
# 6  1003 2020-04-05 Place2 - Place7          Afternoon - Afternoon 2020-04-05 15:00:00.000 2020-04-05 15:00:00.000
# 7  1004 2020-04-05 Place6 - Place7 - Place6 Morning - Afternoon   2020-04-05 07:00:00.000 2020-04-05 15:00:00.000

Я сохранил Time1 и Time2 на случай, если вам все еще нужны полные метки времени. Вам нужно будет обновить функцию time2human, чтобы срезы были более удобными для вас. (У меня есть «часы» -1 и +25, чтобы я полностью связал все возможные часы; я мог бы быть более точным и осторожным с этим, но это достаточно безопасно.)

Наконец, если вы предпочитаете иметь даты и время в тех форматах, с которых вы начали, используйте format(..., format=...), чтобы получить то, что вы хотите; Я предпочитаю (и рекомендую) сохранять их в форматах Date и POSIXt как можно дольше, так как они по своей сути числительны c и поэтому легко сравнимы / сортируемы. Как только они преобразуются в строки, подобные операции становятся менее понятными (например, при попытке сортировки 4/1/2019 до 3/1/2020).

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