使用python或R,组织日历d

2024-05-14 17:41:20 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个记录员工出勤历史的数据框,如下所示:

ID    Sunday Monday Tuesday Wednesday Thursday Friday Saturday
1585    NA      NA      NA      NA        NA      NA     NA
1585    NA       S       S       S         S       H     NA
1585    NA       H       S       S        NA      NA     NA
1585    NA       S       S       S        NA      NA     NA
1597    NA       S       S      NA         S      NA     NA
1597    NA      NA      NA      NA        NA       H     NA
1597    NA      H        S       S        NA      NA     NA
1597    NA      NA      NA      NA        NA      NA     NA

在上述样本中,有两个个体通过ID唯一标识,以下7列是从2017年4月1日开始的周六到周日。有三种出勤行为:S表示病假,H表示节假日,NA表示该员工当天上班。你知道吗

我们的兴趣是重新整理病假记录。例如,1585人从2017年4月10日星期一开始请病假,到2017年4月19日星期三结束,为期10天。请注意,在这10天中,有两天的当地假期,但它将被视为属于这个病假期间。然后,此人于2017年4月24日(星期一)开始第二次病假,并于4月26日(星期三)结束。你知道吗

我们还有一个关于第二个身份证号为1597的人的记录,同样从2017年4月1日开始(因此每个人的记录开始和结束日期是相同的)。此人有三个缺勤期:第一个缺勤期从2017年4月3日星期一开始,到第二天4月4日结束。第二个咒语只持续一天,从4月6日开始到结束。最后一个咒语开始于4月18日,结束于4月19日。你知道吗

所需的输出如下:

ID     Begin_date    End_date    Duration
1585   2017-04-10    2017-04-19   10
1585   2017-04-24    2017-04-26   3
1597   2017-04-03    2017-04-04   2
1597   2017-04-06    2017-04-06   1
1597   2017-04-18    2017-04-19   2

我面临的困难是如何识别连续的病假日期,除此之外,在一个病假期间,可能会有不同类型的出勤类型(假期),但假期仍然被认为属于该病假期间。你知道吗


Tags: 数据id类型date记录员工历史咒语
1条回答
网友
1楼 · 发布于 2024-05-14 17:41:20

你提到你最大的问题之一是认识病假,因为他们可能包括假期和周末。我突然想到病假可以用正则表达式来表示。下面是一个利用这一点的潜在解决方案:

首先,将周末的所有NAs替换为“D”,将工作日的所有NAs替换为“Y”(或其他2个字符)。在您的示例中,正常周末与正常工作日的处理方式不同,因为缺勤拼写可以包含正常周末,但不能包含正常工作日,因此它们应该具有不同的值。你知道吗

然后,对于每个ID,将数据展平,并将其连接成一个字符串。缺勤咒语可以由regex识别为"(S[SHD]*S)|S"。对于找到的每个regex字符串,在新表中创建一行,其中开始日期、结束日期和缺勤时间基于找到的字符串的开始位置、结束位置和长度。你知道吗

为了使这个解决方案起作用,我们需要假设每个ID都有相同数量的行对应于相同的日期,这样我们就可以正确地将字符串的起始位置映射到日期。你知道吗

网友
2楼 · 发布于 2024-05-14 17:41:20

基于@Cholts的思想,我编写了一个R代码来生成所需的输出

#clean the workspace
rm(list=ls(all=TRUE))
require(tidyr)
library(dplyr)
library(lubridate)
library(stringr)

ID = c(rep(1585,4),rep(1597,4))
Sun = c(rep("D",8))
Sat = c(rep("D",8))
Mon = c("Y","S","H","S","S","Y","H","Y")
Tue = c("Y","S","S","S","S","Y","S","Y")
Wed = c("Y","S","S","S","Y","Y","S","Y")
Thur = c("Y","S","Y","Y","S","Y","Y","Y")
Fri = c("Y","H","Y","Y","Y","H","Y","Y")
id_u = unique(ID)
df = data.frame(Sun,Mon,Tue,Wed,Thur,Fri,Sat)

new_df = df %>% unite(new,Sun,Mon,Tue,Wed,Thur,Fri,Sat,remove=FALSE,sep="")
vstr = new_df$new


#===========================================================
idd = c()
begin_date = c()
end_date = c()
duration = c()

n = 2
start_date = ymd('2017-04-02')

for(i in 1:n){
   ps = (i-1)*4 +1
   pe = (i-1)*4 + 4
   indstr = paste(vstr[ps:pe],collapse = "")
   loca = str_locate_all(indstr,"S[SHD]*S|S")

   rn = length(loca[[1]][,1])
   for (j in 1:rn){
     idd = append(idd,id_u[i])
     begin_date = append(begin_date,ymd(start_date+loca[[1]][j,1]-1))
     end_date = append(end_date,ymd(start_date+loca[[1]][j,2]-1))
     duration = append(duration,loca[[1]][j,2]-loca[[1]][j,1]+1)
   }

}

final_df = data.frame(idd,begin_date,end_date,duration)

输出为

> final_df    
   idd begin_date   end_date duration
1 1585 2017-04-10 2017-04-19       10
2 1585 2017-04-24 2017-04-26        3
3 1597 2017-04-03 2017-04-04        2
4 1597 2017-04-06 2017-04-06        1
5 1597 2017-04-18 2017-04-19        2

相关问题 更多 >

    热门问题