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