Это на самом деле просто очень простое применение транспонирования и переноса последнего наблюдения.
Вот мой сотрудник:
emp <- data.frame(empid = 001, timein = as.POSIXct('2018-05-31 8:00'), timeout = as.POSIXct('2018-05-31 17:00'))
Вот мой перенос, перенесенный из последнего наблюдения (ноесть также zoo::na.locf
)
locf <- function(y) c(NA, na.omit(y))[cumsum(!is.na(y))+1]
Теперь транспонировать:
emplong <- reshape(emp, direction='long', idvar='empid', varying=list(2:3),
times=c('in', 'out'), timevar='status')
Это дает:
empid status timein
1.in 1 in 2018-05-31 08:00:00
1.out 1 out 2018-05-31 17:00:00
Теперь создайте список:
roster <- data.frame('times' = seq(
from=as.POSIXct('2018-05-31 00:00:00'),
to=as.POSIXct('2018-06-01 00:00:00'),
by=15*60))
И объединить
roster <- merge(roster, emplong[, -1], by.x='times', by.x='timein', all=T)
И LOCF
roster$status <- locf(roster$status )
roster$status[is.na(roster$status )] <- 'out'
Это дает:
> roster
times status
1 2018-05-31 00:00:00 out
2 2018-05-31 00:15:00 out
3 2018-05-31 00:30:00 out
4 2018-05-31 00:45:00 out
5 2018-05-31 01:00:00 out
...
31 2018-05-31 07:30:00 out
32 2018-05-31 07:45:00 out
33 2018-05-31 08:00:00 in
34 2018-05-31 08:15:00 in
...
67 2018-05-31 16:30:00 in
68 2018-05-31 16:45:00 in
69 2018-05-31 17:00:00 out
70 2018-05-31 17:15:00 out