paiban <- function(
X = Sys.time() + 60*60*24*(-1:1)*1.5 , # 输入时间向量或列数据
x = 'asia/shanghai' , # 时区设定为中国
O = lubridate::force_tz(lubridate::ymd_hms("2021-12-31 07:45:00"), x) , # 初始日期为甲班白班第一天,保留时间用于与X相减
o = hms::as_hms("07:45:00") , # 初始时间为白班七点四十五
P = c('jia','yi','jia','yi','bing','jia','bing','jia','yi','bing','yi','bing') , # 排班顺序表
p = c('bai','ye') # 每日班次表
) {
Q = length(P) # 排班周期
q = length(p) # 一天几个班次
r = unique(P) # 班组名称
R = c() # 先创建一个新的数据集用于填充
for (i in 1: length(r) ) {
R = cbind( R, grep(r[i],P) -1 )
} # 对每个班组填入在一个周期内的索引位置,为方便取余数需要减一
z = c() # 创建新的数据集,每次循环得出的班组班次填入其中
Z = c() # 创建新的数据集,每次循环得出的班组班次汇总填入其中
for (i in 1: length(X) ) {
Y = c() # 用于填充班组
y = c() # 用于填充班次
s = hms:: as_hms(X[i]) # 提取输入时间数据的时间
t = as.numeric(s-o) / (24*60*60/q) # 将该时间与初始时间比较
S =
lubridate::force_tz(
lubridate::ymd_hms(
paste( lubridate:: as_date(X[i])-1, hms:: as_hms( o+(24*60*60/q)*(q-1) ) )
) , x) # 默认(当t<0即早于当天初始时间的时间段)定义为上一天最后一个班次,将其时间改为上一天最后一个班次的最早时间节点
for (j in 1:q) {
if (t >= j-1 & t < j) {
S =
lubridate::force_tz(
lubridate::ymd_hms(
paste( lubridate:: as_date(X[i]), hms:: as_hms( o+(24*60*60/q)*(j-1) ) ) # 日期和时间节点拼接成字符串,再转成日期时间,默认时区UTC
) , x
) # 强行改为中国时区,时间不随时区变动而变动,若想查看时差,可用with_tz函数
}
} # 对不早于当天初始时间的时间段(即t>=0)计算属于哪个班次,将其时间改为当天该班次的最早时间节点
T = (as.numeric(S-O)*q) %% Q # 对日期差取周期的余数,注意需要对日期差乘上每日班次数,方可匹配周期长度=周期天数×每日班次数
for (j in 1: length(r) ) {
if (T %in% R[,j]) {Y = r[j]}
} # 根据各班组在周期中的索引位置-1的结果,匹配日期差与周期的取余结果,可确定班组
y = p[q] # 由于存在早于当天第一个班的最早时间节点的可能,默认设定为上一个班次,即上一天最后一个班次
for (j in 1:q) {
if (t >= j-1 & t < j) {y = p[j]}
} # 根据时间差与每个班次的时间长度的比较,确定班次
z = data.frame(Y,y) # 将班组和班次做成数据框的两列
Z = rbind(Z,z) # 将新的数据框添加在上一个数据框的下面
}
return(Z) # 循环结束(所有时间向量内的元素都处理完后)输出汇总数据框
}
更新,为避免隔夜班次造成的统计困难,对函数进行优化
paiban <- function(
X = Sys.time() + 60*60*24*(-1:1)*0.5 , # 输入时间向量或列数据
x = 'asia/shanghai' , # 时区设定为中国
O = lubridate::force_tz(lubridate::ymd_hms("2021-12-31 07:45:00"), x) , # 初始日期为甲班白班第一天,保留时间用于与X相减
o = hms::as_hms("07:45:00") , # 初始时间为白班七点四十五
P = c('jia','yi','jia','yi','bing','jia','bing','jia','yi','bing','yi','bing') , # 排班顺序表
p = c('bai','ye') # 每日班次表
) {
Q = length(P) # 排班周期
q = length(p) # 一天几个班次
r = unique(P) # 班组名称
R = c() # 先创建一个新的数据集用于填充
for (i in 1: length(r) ) {
R = cbind( R, grep(r[i],P) -1 )
} # 对每个班组填入在一个周期内的索引位置,为方便取余数需要减一
z = c() # 创建新的数据集,每次循环得出的班组班次填入其中
Z = c() # 创建新的数据集,每次循环得出的班组班次汇总填入其中
for (i in 1: length(X) ) {
Y = c() # 用于填充班组
y = c() # 用于填充班次
s = hms:: as_hms(X[i]) # 提取输入时间数据的时间
t = as.numeric(s-o) / (24*60*60/q) # 将该时间与初始时间比较
S =
lubridate::force_tz(
lubridate::ymd_hms(
paste( lubridate:: as_date(X[i])-1, hms:: as_hms( o+(24*60*60/q)*(q-1) ) )
) , x) # 默认(当t<0即早于当天初始时间的时间段)定义为上一天最后一个班次,将其时间改为上一天最后一个班次的最早时间节点
for (j in 1:q) {
if (t >= j-1 & t < j) {
S =
lubridate::force_tz(
lubridate::ymd_hms(
paste( lubridate:: as_date(X[i]), hms:: as_hms( o+(24*60*60/q)*(j-1) ) ) # 日期和时间节点拼接成字符串,再转成日期时间,默认时区UTC
) , x
) # 强行改为中国时区,时间不随时区变动而变动,若想查看时差,可用with_tz函数
}
} # 对不早于当天初始时间的时间段(即t>=0)计算属于哪个班次,将其时间改为当天该班次的最早时间节点
T = (as.numeric(S-O)*q) %% Q # 对日期差取周期的余数,注意需要对日期差乘上每日班次数,方可匹配周期长度=周期天数×每日班次数
for (j in 1: length(r) ) {
if (T %in% R[,j]) {Y = r[j]}
} # 根据各班组在周期中的索引位置-1的结果,匹配日期差与周期的取余结果,可确定班组
y = paste(lubridate:: as_date(X[i])-1, p[q]) # 由于存在早于当天第一个班的最早时间节点的可能,默认设定为上一个班次,即上一天最后一个班次
for (j in 1:q) {
if (t >= j-1 & t < j) {y = paste(lubridate:: as_date(X[i]), p[j])}
} # 根据时间差与每个班次的时间长度的比较,确定班次
z = data.frame(Y,y) # 将班组和班次做成数据框的两列
Z = rbind(Z,z) # 将新的数据框添加在上一个数据框的下面
}
return(Z) # 循环结束(所有时间向量内的元素都处理完后)输出汇总数据框
}
更新:考虑到日期以字符串形式保存后绘图和排序,11会排在2前面(因为是字符向量),所以增加日期列。
paiban <- function(
X = Sys.time() + 60*60*24*(-1:1)*0.5 , # 输入时间向量或列数据
x = 'asia/shanghai' , # 时区设定为中国
O = lubridate::force_tz(lubridate::ymd_hms("2021-12-31 07:45:00"), x) , # 初始日期为甲班白班第一天,保留时间用于与X相减
o = hms::as_hms("07:45:00") , # 初始时间为白班七点四十五
P = c('jia','yi','jia','yi','bing','jia','bing','jia','yi','bing','yi','bing') , # 排班顺序表
p = c('bai','ye') # 每日班次表
) {
Q = length(P) # 排班周期
q = length(p) # 一天几个班次
r = unique(P) # 班组名称
R = c() # 先创建一个新的数据集用于填充
for (i in 1: length(r) ) {
R = cbind( R, grep(r[i],P) -1 )
} # 对每个班组填入在一个周期内的索引位置,为方便取余数需要减一
z = c() # 创建新的数据集,每次循环得出的班组班次填入其中
Z = c() # 创建新的数据集,每次循环得出的班组班次汇总填入其中
for (i in 1: length(X) ) {
Y = c() # 用于填充班组
y = c() # 用于填充班次
ydate = c() # 用于填充班次所属日期
s = hms:: as_hms(X[i]) # 提取输入时间数据的时间
t = as.numeric(s-o) / (24*60*60/q) # 将该时间与初始时间比较
S =
lubridate::force_tz(
lubridate::ymd_hms(
paste( lubridate:: as_date(X[i])-1, hms:: as_hms( o+(24*60*60/q)*(q-1) ) )
) , x) # 默认(当t<0即早于当天初始时间的时间段)定义为上一天最后一个班次,将其时间改为上一天最后一个班次的最早时间节点
for (j in 1:q) {
if (t >= j-1 & t < j) {
S =
lubridate::force_tz(
lubridate::ymd_hms(
paste( lubridate:: as_date(X[i]), hms:: as_hms( o+(24*60*60/q)*(j-1) ) ) # 日期和时间节点拼接成字符串,再转成日期时间,默认时区UTC
) , x
) # 强行改为中国时区,时间不随时区变动而变动,若想查看时差,可用with_tz函数
}
} # 对不早于当天初始时间的时间段(即t>=0)计算属于哪个班次,将其时间改为当天该班次的最早时间节点
T = (as.numeric(S-O)*q) %% Q # 对日期差取周期的余数,注意需要对日期差乘上每日班次数,方可匹配周期长度=周期天数×每日班次数
for (j in 1: length(r) ) {
if (T %in% R[,j]) {Y = r[j]}
} # 根据各班组在周期中的索引位置-1的结果,匹配日期差与周期的取余结果,可确定班组
y = paste(lubridate:: as_date(X[i])-1, p[q]) # 由于存在早于当天第一个班的最早时间节点的可能,默认设定为上一个班次,即上一天最后一个班次
for (j in 1:q) {
if (t >= j-1 & t < j) {y = paste(lubridate:: as_date(X[i]), p[j])}
} # 根据时间差与每个班次的时间长度的比较,确定班次
ydate = lubridate:: as_date(X[i])-1
for (j in 1:q) {
if (t >= j-1 & t < j) {ydate = lubridate:: as_date(X[i])}
}
z = data.frame(Y,y,ydate) # 将班组和班次做成数据框的两列
Z = rbind(Z,z) # 将新的数据框添加在上一个数据框的下面
}
return(Z) # 循环结束(所有时间向量内的元素都处理完后)输出汇总数据框
}
应用
jingzheng1 %>%
group_by(
jitai = Machine,
riqi = ydate,
banci = y,
banzu = Y) %>%
summarise(
.groups = "keep",
chanliang = F_ExitWeight %>% sum()/1000,
lailiao = F_CoilID %>% na.omit() %>% unique() %>% length(),
chengpin = NewCoilNumber %>% na.omit() %>% unique() %>% length()
) %>%
View()