【问题标题】:Find time difference between two columns based on unique id and add the absence days根据唯一ID查找两列之间的时间差并添加缺勤天数
【发布时间】:2018-08-02 06:52:08
【问题描述】:

我遇到了一个问题,我想找出员工的缺勤天数,如果他连续 3 天不来,它应该在新列中添加 3 天(可能会持续多天)问题是开始日期和结束日期在那里,所以如果员工相同,我想匹配,下一个缺勤的开始日期是连续的一天,它应该添加它,我在这里附上屏幕截图和表格索引。 Excel 或 R 的任何帮助都会有所帮助。我已经尝试过Max ifSumif。唯一的问题是,如果他/她连续几天缺席,我只想要添加

ID  START_DATE  END_DATE    ABSENCE_DAYS
3   14-06-18    14-06-18    1
3   17-06-18    17-06-18    1
3   18-06-18    18-06-18    1
4   01-06-18    01-06-18    1
4   04-06-18    04-06-18    1
4   21-06-18    22-06-18    2
4   27-06-18    27-06-18    1
4   28-06-18    28-06-18    1
4   04-07-18    04-07-18    1
4   05-07-18    05-07-18    1
4   09-07-18    09-07-18    1
4   11-07-18    11-07-18    1
4   23-07-18    23-07-18    1
4   24-07-18    24-07-18    1
4   25-07-18    25-07-18    1
5   07-06-18    08-06-18    2
5   28-06-18    28-06-18    1
5   27-07-18    27-07-18    0.5
6   10-06-18    11-06-18    2
6   17-06-18    21-06-18    5
6   24-06-18    25-06-18    2
6   26-06-18    03-07-18    6
6   15-07-18    15-07-18    1
6   22-07-18    22-07-18    1

例如,员工 4 在 23,24 和 25 日连续休假 3 次,因此在新列中显示他连续 3 天缺勤。

更新

所需的输出看起来像这样,这只是一个示例

【问题讨论】:

  • 这样的问题有好几个,这里只有一个:stackoverflow.com/q/50194816/4961700
  • 你有时间戳,或者你如何计算0.5天?
  • @SolarMike 感谢您的快速回复,但我的问题与您提供的问题不同。
  • @Stephan 现在我们可以忽略时间戳,只添加缺席天数。这就是我卡住的地方。谢谢
  • 您可以为示例数据添加所需的输出吗?

标签: r excel datetime excel-formula


【解决方案1】:

这是使用data.table 的解决方案。您可以检查当前行的 START_DATE 是否比上一行的 END_DATE 晚一天,并使用cumsum 将它们组合在一起。之后,只要您可以将它们正确分组,它就只是 ABSENCE_DAYS 的简单总和。

welfare[, TOTAL_ABSENCE := sum(ABSENCE_DAYS), 
    by=.(ID, cumsum(START_DATE != shift(END_DATE, fill=1L) + 1L))]

输出:

    ID START_DATE   END_DATE ABSENCE_DAYS TOTAL
 1:  3 2018-06-14 2018-06-14          1.0   1.0
 2:  3 2018-06-17 2018-06-17          1.0   2.0
 3:  3 2018-06-18 2018-06-18          1.0   2.0
 4:  4 2018-06-01 2018-06-01          1.0   1.0
 5:  4 2018-06-04 2018-06-04          1.0   1.0
 6:  4 2018-06-21 2018-06-22          2.0   2.0
 7:  4 2018-06-27 2018-06-27          1.0   2.0
 8:  4 2018-06-28 2018-06-28          1.0   2.0
 9:  4 2018-07-04 2018-07-04          1.0   2.0
10:  4 2018-07-05 2018-07-05          1.0   2.0
11:  4 2018-07-09 2018-07-09          1.0   1.0
12:  4 2018-07-11 2018-07-11          1.0   1.0
13:  4 2018-07-23 2018-07-23          1.0   3.0
14:  4 2018-07-24 2018-07-24          1.0   3.0
15:  4 2018-07-25 2018-07-25          1.0   3.0
16:  5 2018-06-07 2018-06-08          2.0   2.0
17:  5 2018-06-28 2018-06-28          1.0   1.0
18:  5 2018-07-27 2018-07-27          0.5   0.5
19:  6 2018-06-10 2018-06-11          2.0   2.0
20:  6 2018-06-17 2018-06-21          5.0   5.0
21:  6 2018-06-24 2018-06-25          2.0   8.0
22:  6 2018-06-26 2018-07-03          6.0   8.0
23:  6 2018-07-15 2018-07-15          1.0   1.0
24:  6 2018-07-22 2018-07-22          1.0   1.0
    ID START_DATE   END_DATE ABSENCE_DAYS TOTAL

数据:

library(data.table)
welfare <- fread(
"ID  START_DATE  END_DATE    ABSENCE_DAYS
3   14-06-18    14-06-18    1
3   17-06-18    17-06-18    1
3   18-06-18    18-06-18    1
4   01-06-18    01-06-18    1
4   04-06-18    04-06-18    1
4   21-06-18    22-06-18    2
4   27-06-18    27-06-18    1
4   28-06-18    28-06-18    1
4   04-07-18    04-07-18    1
4   05-07-18    05-07-18    1
4   09-07-18    09-07-18    1
4   11-07-18    11-07-18    1
4   23-07-18    23-07-18    1
4   24-07-18    24-07-18    1
4   25-07-18    25-07-18    1
5   07-06-18    08-06-18    2
5   28-06-18    28-06-18    1
5   27-07-18    27-07-18    0.5
6   10-06-18    11-06-18    2
6   17-06-18    21-06-18    5
6   24-06-18    25-06-18    2
6   26-06-18    03-07-18    6
6   15-07-18    15-07-18    1
6   22-07-18    22-07-18    1")    
cols <- c("START_DATE", "END_DATE")
welfare[, (cols) := lapply(.SD, as.Date, format="%d-%m-%y"), .SDcols=cols]

【讨论】:

    【解决方案2】:

    使用dplyr::lagdplyr::lead我们可以检查END和START是否是连续的

    library(dplyr)
    library(lubridate)
    data %>% group_by(ID) %>% 
              mutate(Forward = dmy(START_DATE)-lag(dmy(END_DATE)), Backward = dmy(END_DATE)-lead(dmy(START_DATE)), 
                     Flag=ifelse(Forward==1 | Backward==-1, TRUE,FALSE), 
                     Total=sum(ABSENCE_DAYS[Flag],na.rm = T)) 
    

    数据

    data <- read.table(text="
                  ID  START_DATE  END_DATE    ABSENCE_DAYS
                   3   14-06-18    14-06-18    1
                   3   17-06-18    17-06-18    1
                   3   18-06-18    18-06-18    1
                   4   01-06-18    01-06-18    1
                   4   04-06-18    04-06-18    1
                   4   21-06-18    22-06-18    2
                   4   27-06-18    27-06-18    1
                   4   28-06-18    28-06-18    1
                   4   04-07-18    04-07-18    1
                   4   05-07-18    05-07-18    1
                   4   09-07-18    09-07-18    1
                   4   11-07-18    11-07-18    1
                   4   23-07-18    23-07-18    1
                   4   24-07-18    24-07-18    1
                   4   25-07-18    25-07-18    1
                   5   07-06-18    08-06-18    2
                   5   28-06-18    28-06-18    1
                   5   27-07-18    27-07-18    0.5
                   6   10-06-18    11-06-18    2
                   6   17-06-18    21-06-18    5
                   6   24-06-18    25-06-18    2
                   6   26-06-18    03-07-18    6
                   6   15-07-18    15-07-18    1
                   6   22-07-18    22-07-18    1
                   6   22-07-18    22-07-18    1
                   ",header=T, stringsAsFactors = F)
    

    【讨论】:

    • 谢谢只是缺勤天数不匹配,例如 id 4 答案应该是 3 而我得到了 5 个缺勤天数
    • @Hunaidkhan 抱歉,没有数据很难猜测。尝试仔细检查 id 4
    • 我已经检查了所有字段的缺勤总和没有到来,这里的转发函数将所有的值按顺序排列,但不是连续的日期。我只想计算一天的结束日期和另一天的开始日期连续的天数,希望你理解
    • 是的,向前和向后是辅助列,并返回许多值。 Flag 在前进和后退 ==1 或 -1 时是否返回 TRUE 和 FALSE。
    • 是的,它返回 true 和 false,但它是做什么的
    猜你喜欢
    • 1970-01-01
    • 2013-07-12
    • 1970-01-01
    • 2014-04-17
    • 1970-01-01
    • 2016-05-02
    • 1970-01-01
    • 2016-06-12
    • 1970-01-01
    相关资源
    最近更新 更多