У меня есть большой набор данных, который содержит 1. дату приема (день, месяц, год, час, минута - все в отдельных столбцах) и время и 2. дату и время отъезда (объединенные в один столбец).

Но данные имеют формат, который затрудняет расчет продолжительности приема.

  day  month  year  hour  minute  departuredatetime2
1 6    10     2010  14    20      6/12/2010 17:20
2 26   10     2010  19    25      26/10/2010 21:25
3 10   12     2010  14    30      10/12/2010 17:00
4 14   4      2011  13    00      14/04/2011 16:45
5 20   1      2012  12    30      20/01/2012 15:30
6 20   2      2012  23    30      21/02/2012 03:30
.
.
1095

Я надеюсь добиться чего-то вроде

   admissionduration(hours)
1  3.0
2  2.0
3  2.5
4  3.75
5  3.0
6  4.0
.
.
1095

Я не слишком уверен, как подойти к этому в R, не уверен, как я могу вычесть дату и время приема из даты и времени отъезда.

Спасибо за ваше время

r
0
Tina 29 Июл 2020 в 16:43

3 ответа

Лучший ответ

Вот способ использования функций tidyverse:

library(dplyr)

df %>%
  tidyr::unite(d1, -departuredatetime2, sep = "-") %>%
  mutate(across(.fns = lubridate::dmy_hm), 
         diff_hour = as.numeric(difftime(departuredatetime2, d1, units = 'hour')))


#                   d1  departuredatetime2 diff_hour
#1 2010-12-06 14:20:00 2010-12-06 17:20:00      3.00
#2 2010-10-26 19:25:00 2010-10-26 21:25:00      2.00
#3 2010-12-10 14:30:00 2010-12-10 17:00:00      2.50
#4 2011-04-14 13:00:00 2011-04-14 16:45:00      3.75
#5 2012-01-20 12:30:00 2012-01-20 15:30:00      3.00
#6 2012-02-20 23:30:00 2012-02-21 03:30:00      4.00

В базе R вы можете:

df$d1 <- do.call(paste, df[-6])
df$d1 <- as.POSIXct(df$d1, format = "%d %m %Y %H %M")
df$departuredatetime2 <- as.POSIXct(df$departuredatetime2, 
                            format = "%d/%m/%Y%H:%M")
df$diff_hour <- as.numeric(difftime(df$departuredatetime2, df$d1, units = 'hour'))

Логика в обоих подходах остается одинаковой: мы объединяем все столбцы, кроме последнего, чтобы получить метку времени (d1), и вычитаем ее с помощью departuredatetime2, чтобы получить разницу в часах.

0
Ronak Shah 29 Июл 2020 в 14:01

В качестве простого решения вы можете использовать несколько функций из пакета lubridate для этого.

  • Преобразуйте несколько столбцов допуска с помощью make_datetime().
  • Преобразуйте один столбец отправления в объект даты и времени с помощью dmy_hm().
  • Проверьте интервал между отправлением и приемом с помощью %--% и получите результат в часов, разделив это на один час с помощью dhours(1).
library(dplyr)
library(lubridate)

# 1. merge and convert admission columns to one POSIXct date and time object
# 2. convert departure column to a POSIXct date and time object
# 3. count a difference between admission and departure and display that in hours
df %>%
  mutate(admission               = make_datetime(year, month, day, hour, minute),
         departure               = dmy_hm(departuredatetime2),
         admissionduration_hours = admission %--% departure / dhours(1))
#>   day month year hour minute departuredatetime2           admission
#> 1   6    10 2010   14     20    6/10/2010 17:20 2010-10-06 14:20:00
#> 2  26    10 2010   19     25   26/10/2010 21:25 2010-10-26 19:25:00
#> 3  10    12 2010   14     30   10/12/2010 17:00 2010-12-10 14:30:00
#> 4  14     4 2011   13      0   14/04/2011 16:45 2011-04-14 13:00:00
#> 5  20     1 2012   12     30   20/01/2012 15:30 2012-01-20 12:30:00
#> 6  20     2 2012   23     30   21/02/2012 03:30 2012-02-20 23:30:00
#>             departure admissionduration_hours
#> 1 2010-10-06 17:20:00                    3.00
#> 2 2010-10-26 21:25:00                    2.00
#> 3 2010-12-10 17:00:00                    2.50
#> 4 2011-04-14 16:45:00                    3.75
#> 5 2012-01-20 15:30:00                    3.00
#> 6 2012-02-21 03:30:00                    4.00

Создано в 2020-07-29 с помощью пакетаprex (v0.3.0)

Данные

df <- structure(list(day = c(6L, 26L, 10L, 14L, 20L, 20L), month = c(10L, 
10L, 12L, 4L, 1L, 2L), year = c(2010L, 2010L, 2010L, 2011L, 2012L, 
2012L), hour = c(14L, 19L, 14L, 13L, 12L, 23L), minute = c(20L, 
25L, 30L, 0L, 30L, 30L), departuredatetime2 = c("6/10/2010 17:20", 
"26/10/2010 21:25", "10/12/2010 17:00", "14/04/2011 16:45", "20/01/2012 15:30", 
"21/02/2012 03:30")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))
0
Petr Kajzar 29 Июл 2020 в 16:11

Этот подход с регулярным выражением должен работать:

Пример данных:

df <- data.frame(
  hour = c("14","19","14","13"),
  min = c("20","25","30","00"),
  departure = c("6/12/2010 17:20", "26/10/2010 21:25", "10/12/2010 17:00", "14/04/2011 16:45")
)

Сначала рассчитайте время приема:

admissions <- as.numeric(hm(paste0(df$hour, ":", df$min)))

Затем рассчитайте время отправления:

departures <- as.numeric(hm(sub(".*(\\d{2}:\\d{2})", "\\1", df$departure)))

Наконец, рассчитайте разницу во времени в часах:

df$admissionduration <- (departures - admissions)/3600

Результат:

df
  hour min        departure admissionduration
1   14  20  6/12/2010 17:20              3.00
2   19  25 26/10/2010 21:25              2.00
3   14  30 10/12/2010 17:00              2.50
4   13  00 14/04/2011 16:45              3.75
0
Chris Ruehlemann 29 Июл 2020 в 14:41