根据R中的日班和夜班变化数据帧

根据R中的日班和夜班变化数据帧,r,dplyr,R,Dplyr,我的目标是通过白班和夜班来改变数据帧,其中白班定义为6:45-18:45,夜班定义为18:45-6:45。我的问题是,我无法正确划分夜班,因为夜班发生在两个不同的日期。我期望的结果如下 date time shift 17/08/2018 23:40:00 Night 1 17/08/2018 23:56:00 Night 1 18/08/2018 00:33:00 Night 1 18/08/2018 04:02:00 Ni

我的目标是通过白班和夜班来改变数据帧,其中白班定义为6:45-18:45,夜班定义为18:45-6:45。我的问题是,我无法正确划分夜班,因为夜班发生在两个不同的日期。我期望的结果如下

 date        time        shift
    17/08/2018  23:40:00 Night 1
    17/08/2018  23:56:00 Night 1
    18/08/2018  00:33:00 Night 1
    18/08/2018  04:02:00 Night 1
    18/08/2018  08:03:00 Day 1
    18/08/2018  12:25:00 Day 1
    18/08/2018  22:30:00 Night 2
然而,我的代码产生

 date        time        shift
    17/08/2018  23:40:00 Night 1
    17/08/2018  23:56:00 Night 1
    18/08/2018  00:33:00 Night 2
    18/08/2018  04:02:00 Night 2
    18/08/2018  08:03:00 Day 1
    18/08/2018  12:25:00 Day 1
    18/08/2018  22:30:00 Night 2
我使用的代码是

am_shift_start = as.numeric(lubridate::hms("06:45:00"))
am_shift_end = as.numeric(lubridate::hms("18:45:00"))
merged_csv$DATE = as.Date(merged_csv$DATE, format = "%m%d%Y")
merged_csv = merged_csv %>%
  group_by(DATE) %>%
  mutate(shift = if_else((as.numeric(TIME) >= am_shift_end |
                            as.numeric(TIME) <= am_shift_start), "Night shift", "Day_shift")) %>%
  arrange(DATE, TIME)
有没有更简单的方法(甚至是工作方法)?谢谢

编辑:将示例数据添加为数据帧

merged_csv = data.frame(
  "date" =   c("17/08/2018",  "17/08/2018" , "18/08/2018", "18/08/2018",  "18/08/2018", "18/08/2018",  "18/08/2018"),
  "time" = c("23:40:00", "23:56:00", "00:33:00", "04:02:00", "08:03:00", "12:25:00", "22:30:00")
)
merged_csv$date = as.Date(merged_csv$date, format = "%d/%m/%Y")
merged_csv$time = lubridate::hms(merged_csv$time) #
库(dplyr)
图书馆(lubridate)
合并的\u csv%>%
变异(
班次i=findInterval(时间,hms(c(“00:00:00”、“08:00:00”、“18:30:00”、“24:00:01”)),
班次=粘贴(如果有其他情况(班次=2L,“白天”,“晚上”),
日期-最小值(日期)+(班次=3L))
)
#日期时间班次
#1 2018-08-17 23小时40米0秒3夜1
#2 2018-08-17 23小时56米0秒3夜1
#3 2018-08-18 3300米1晚1
#2018年8月18日夜间
#2018年8月18日第1天
#6 2018-08-18第1天12小时25百万
#7 2018-08-18 22小时30米0秒3夜2
关键是要区分“班次”,不仅是白天和黑夜,还有午夜前的晚上和午夜后的晚上。

这里有一个选项:

library(dplyr)
library(lubridate)

df %>%
  tidyr::unite(datetime, date, time, sep = ' ') %>%
  arrange(datetime) %>%
  mutate(datetime = dmy_hms(datetime), 
         hour = hour(datetime), 
         mins = minute(datetime),
         shift = case_when(hour == 6 & mins >= 45 |
                                  between(hour, 7, 17) | 
                                  hour == 18 & mins <= 45 ~ 'Day', 
                                  TRUE ~ 'Night'), 
         day = data.table::rleid(shift)) %>%
  group_by(shift) %>%
  transmute(datetime, 
            result = paste(shift, match(day, unique(day)))) %>%
  ungroup() %>%
  select(-shift)

#  datetime            result 
#  <dttm>              <chr>  
#1 2020-08-17 23:40:00 Night 1
#2 2018-08-17 23:56:00 Night 1
#3 2018-08-18 00:33:00 Night 1
#4 2018-08-18 04:02:00 Night 1
#5 2018-08-18 08:03:00 Day 1  
#6 2018-08-18 12:25:00 Day 1  
#7 2018-08-18 22:30:00 Night 2

请检查,我认为您可以使用任何一个答案(无需
循环)。您可以从
merged\u csv
发布一些行吗?@r2evans感谢链接,但我相信我的代码已经做到了这一点。我想对其进行修改,以提供独特的日班/夜班。@AnilGoyal我在底部添加了一个与给定示例相关的小数据框。2020年与2018年是一个输入错误,还是年份不是哪个日数的一个因素?这真的很酷。非常感谢。我喜欢这样,但最好不要把日期和时间结合起来。谢谢
library(dplyr)
library(lubridate)

df %>%
  tidyr::unite(datetime, date, time, sep = ' ') %>%
  arrange(datetime) %>%
  mutate(datetime = dmy_hms(datetime), 
         hour = hour(datetime), 
         mins = minute(datetime),
         shift = case_when(hour == 6 & mins >= 45 |
                                  between(hour, 7, 17) | 
                                  hour == 18 & mins <= 45 ~ 'Day', 
                                  TRUE ~ 'Night'), 
         day = data.table::rleid(shift)) %>%
  group_by(shift) %>%
  transmute(datetime, 
            result = paste(shift, match(day, unique(day)))) %>%
  ungroup() %>%
  select(-shift)

#  datetime            result 
#  <dttm>              <chr>  
#1 2020-08-17 23:40:00 Night 1
#2 2018-08-17 23:56:00 Night 1
#3 2018-08-18 00:33:00 Night 1
#4 2018-08-18 04:02:00 Night 1
#5 2018-08-18 08:03:00 Day 1  
#6 2018-08-18 12:25:00 Day 1  
#7 2018-08-18 22:30:00 Night 2
df <- structure(list(date = c("17/08/2020", "17/08/2018", "18/08/2018", 
"18/08/2018", "18/08/2018", "18/08/2018", "18/08/2018"), time = c("23:40:00", 
"23:56:00", "00:33:00", "04:02:00", "08:03:00", "12:25:00", "22:30:00"
)), class = "data.frame", row.names = c(NA, -7L))