如何更改 R 中一系列可能时间组合的计划工作

How to change the schedule work for a range of possible time combinations in R

这是我的数据集 dput()

timeset=structure(list(SAP = c("S412", "S412", "S412", "S412", "S412", 
"S412", "S412", "S412", "S412", "S412", "S412", "S412", "S412", 
"S412", "S412", "S412", "S412"), weekday = c(1L, 1L, 2L, 2L, 
3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 6L, 7L, 7L), tab = c(1001L, 
1002L, 1001L, 1003L, 1001L, 1002L, 1001L, 1002L, 1003L, 1001L, 
1002L, 1003L, 1001L, 1002L, 1003L, 1001L, 1003L), date = c(20220411L, 
20220411L, 20220412L, 20220412L, 20220413L, 20220413L, 20220414L, 
20220414L, 20220414L, 20220415L, 20220415L, 20220415L, 20220416L, 
20220416L, 20220416L, 20220417L, 20220417L), stuff_code = c(801L, 
690L, 690L, 690L, 1180L, 690L, 1180L, 690L, 690L, 1180L, 690L, 
690L, 1180L, 690L, 690L, 1180L, 690L), TS = c(9L, 9L, 9L, 9L, 
9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L), TE = c(21L, 
21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 21L, 
21L, 21L, 21L)), class = "data.frame", row.names = c(NA, -17L
))

我在两种可能的人员安排情况下遇到了很大的困难

第一种情况

有时会发生这样的情况,例如在 weekday=4 上,2 个人与 stuff_code=690 一起工作,而 1 个人与 stuff_code=1180 一起工作。如何做到这一点,如果有一天两个人 with stuff_code=690 同时工作并且 stuff_code=1180 和他们 stuff_code=690 有相同的开始时间 TS 和时间结束TE,然后对于这些 code=690 将开始和结束时间更改为 10 小时间隔,例如第一个 stuff_code 是 9-19,第二个是 11-21,所以两者将工作 10 小时以保持商店工作范围为 9-21,不需要同时设置为 9-19。 (stuff=1180我们不touch.it只是说明发生了一个情况2人690和1人1180)

第二种情况

有些日子stuff_code=690同时工作(工作日=2),因为他们需要同样根据10小时范围更改时间,第一个从9-19,第二个从11 -21 好吧,或者如果指示了从 10-22 开始的时间,那么从 10-20 开始,第二个从 12-22 开始。

如果有一天像 weekend=1 只有两个人工作,我们也会这样做,但是其中一个 stuff_code=801 和第二个 stuff_code=690,他们同时工作,然后我们为他们更改时间,其中 801 应该是第一个最早的日期,例如,801 从 9-19 开始,690 从 11-21

在这种可能的情况下更改图表的最简单方法是什么?

我在 excel

中手动执行的所需输出
SAP weekday tab date    stuff_code  TS  TE
**S412  1   1001    20220411    801 9   19
S412    1   1002    20220411    690 11  21
S412    2   1001    20220412    690 9   19
S412    2   1003    20220412    690 11  21**
S412    3   1001    20220413    1180    9   21
S412    3   1002    20220413    690 9   21
**S412  4   1001    20220414    1180    9   21
S412    4   1002    20220414    690 9   19
S412    4   1003    20220414    690 11  21
S412    5   1001    20220415    1180    9   21
S412    5   1002    20220415    690 9   19
S412    5   1003    20220415    690 11  21
S412    6   1001    20220416    1180    9   21
S412    6   1002    20220416    690 9   19
S412    6   1003    20220416    690 11  21**
S412    7   1001    20220417    1180    9   21
S412    7   1003    20220417    690 9   21

** 标记了我更改小时的工作日。

您可以编写一个小函数,f 来处理逻辑,然后将该函数应用于每个日期:

f <- function(cd,s,e) {
  
  new_hours <- function(cd,s,e) {
    s[cd!=1180] <- c(min(s),min(s)+2)
    e[cd!=1180] <- c(max(e)-2,max(e))
    list(s,e)
  }
  
  ## Situation 1 and 2
  if(sum(cd==690)==2 & length(unique(s[cd==690]))==1 & length(unique(e[cd==690]))==1) {
      newh = new_hours(cd,s,e)
      s = newh[[1]]
      e = newh[[2]]
  }
  ## Situation 3
  if(length(cd==2) & (690 %in% cd) & (801 %in% cd)) {
    if(length(unique(s))==1 & length(unique(e))==1) {
      newh = new_hours(cd,s,e)
      s = newh[[1]][order(cd, decreasing=T)]
      e = newh[[2]][order(cd, decreasing=T)]
    }
  }
  return(list(as.integer(cd),as.integer(s),as.integer(e)))
}

library(data.table)
setDT(timeset)
timeset[, c("stuff_code", "TS", "TE"):=f(stuff_code, TS, TE), by=date]

输出:

       SAP weekday   tab     date stuff_code    TS    TE
    <char>   <int> <int>    <int>      <int> <int> <int>
 1:   S412       1  1001 20220411        801     9    19
 2:   S412       1  1002 20220411        690    11    21
 3:   S412       2  1001 20220412        690     9    19
 4:   S412       2  1003 20220412        690    11    21
 5:   S412       3  1001 20220413       1180     9    21
 6:   S412       3  1002 20220413        690     9    21
 7:   S412       4  1001 20220414       1180     9    21
 8:   S412       4  1002 20220414        690     9    19
 9:   S412       4  1003 20220414        690    11    21
10:   S412       5  1001 20220415       1180     9    21
11:   S412       5  1002 20220415        690     9    19
12:   S412       5  1003 20220415        690    11    21
13:   S412       6  1001 20220416       1180     9    21
14:   S412       6  1002 20220416        690     9    19
15:   S412       6  1003 20220416        690    11    21
16:   S412       7  1001 20220417       1180     9    21
17:   S412       7  1003 20220417        690     9    21