Создание столбца на основе временного диапазона

#r #time

#r #время

Вопрос:

Я пытался создать новый столбец на основе временного диапазона: пунктуальный (до 12:00:00), поздний (с 12:00:00 до 15:00:00) и очень поздний (после 15:00:00). Я могу создать столбец на основе фиксированного времени, а не диапазона.

Данные

                  time worker Day
1 2020-07-21 15:25:00   Ryan Tue
2 2020-07-21 11:20:00    Tim Tue
3 2020-07-21 11:30:00   John Tue
4 2020-07-21 14:00:00   Adam Tue
  

Желаемый результат

                  time worker Day   Arrival
1 2020-07-21 15:25:00   Ryan Tue very late
2 2020-07-21 11:20:00    Tim Tue  punctual
3 2020-07-21 11:30:00   John Tue  punctual
4 2020-07-21 14:00:00   Adam Tue      late
  

код ошибки

 df<-df %>% mutate(hour = lubridate::hour(time), minutes = lubridate::minutes(time),Arrival = case_when(hour <- 12 | (hour == 12 amp; minutes <= 30) ~ 'punctual', 
                                                                                             hour <- 15 | (hour == 15 amp; minutes <= 30) ~ 'late',
                                                                                             TRUE ~ 'very late'))
  

Ответ №1:

Вы можете использовать case_when и указывать каждое условие по отдельности :

 library(dplyr)
library(lubridate)

df %>%
  mutate(hour = hour(time),
         Arrival = case_when(hour < 12 ~ 'punctual', 
                             hour < 15 ~ 'late', 
                             TRUE ~ 'very late'))
  

Или используйте cut в базовом R, указав разрывы.

 df$Arrival <- cut(as.integer(format(df$time, '%H')), c(0, 11, 14, 23), 
                  c('punctual', 'late', 'very late'))

df
#                 time worker Day    Arrival
#1 2020-07-21 15:25:00   Ryan Tue  very late
#2 2020-07-21 11:20:00    Tim Tue   punctual
#3 2020-07-21 11:30:00   John Tue   punctual
#4 2020-07-21 14:00:00   Adam Tue       late
  

Чтобы расширить это для точности до минутного уровня, мы можем использовать case_when как :

 df %>% 
  mutate(hour = hour(time), 
         minutes = minute(time),
         Arrival = case_when(
                hour < 12 | (hour == 12 amp; minutes <= 30) ~ 'punctual', 
                hour < 15 | (hour == 15 amp; minutes <= 30) ~ 'late',
                TRUE ~ 'very late'))
  

данные

Убедитесь, что time столбец относится к классу POSIXct в ваших данных.

 df <- structure(list(time = structure(c(1595345100, 1595330400, 1595331000, 
1595340000), class = c("POSIXct", "POSIXt"), tzone = "UTC"), 
    worker = c("Ryan", "Tim", "John", "Adam"), Day = c("Tue", 
  "Tue", "Tue", "Tue")), row.names = c("1", "2", "3", "4"), class = "data.frame")
  

Комментарии:

1. Спасибо, Ронак Шах! Что, если это было 12:30:00 и 15:30:00?

2. Исходя из логики здесь это было бы 'late' и 'very late' соответственно для них.

3. что касается критериев, что, если я хочу также включить минуты?

4. В этом случае вы можете использовать следующий case_when подход. Аналогично hour созданию другого minutes столбца lubridate::minutes и изменению условия. Например, если вы хотите, чтобы время до 12.30 было «пунктуальным». Выполните hour < 12 | (hour == 12 amp; minutes <= 30 ~ 'punctual' и так далее для других условий.

5. Я столкнулся с этой ошибкой в lapply(pieces, as.numeric) : NAs introduced by coercion . Я вставлю свой текущий код в вопрос выше