Во-первых, я думаю, что ваш формат свертывания 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
).