Search code examples
rdata.tabletime-seriesiranges

using r to check the shift in manufacturing plant based on the timestamp


By using the timestamp of produced unit, i want to check in which shift it was produced. Basically the production is carried out in two shifts per day. shifts timings are 06:00 to 18:00 and 18:00 to 06:00. shifts data frame below shows the planning of shifts of december month.

let me make it more clear

2015-12-01         A shift(2015-12-01 06:00:00 to 2015-12-01 17:59:59)                       
2015-12-01         D shift(2015-12-01 18:00:00 to 2015-12-02 05:59:59)
2015-12-02         A shift(2015-12-02 06:00:00 to 2015-12-02 17:59:59)
2015-12-02         D shift(2015-12-02 18:00:00 to 2015-12-03 05:59:59)
and so on..

head(shifts)
        date day_shift night_shift
1 2015-12-01         A           D
2 2015-12-02         A           D
3 2015-12-03         B           A
4 2015-12-04         B           A
5 2015-12-05         C           B
6 2015-12-06         C           B 


shifts <- structure(list(date = structure(1:31, .Label = c("2015-12-01", 
    "2015-12-02", "2015-12-03", "2015-12-04", "2015-12-05", "2015-12-06", 
    "2015-12-07", "2015-12-08", "2015-12-09", "2015-12-10", "2015-12-11", 
    "2015-12-12", "2015-12-13", "2015-12-14", "2015-12-15", "2015-12-16", 
    "2015-12-17", "2015-12-18", "2015-12-19", "2015-12-20", "2015-12-21", 
    "2015-12-22", "2015-12-23", "2015-12-24", "2015-12-25", "2015-12-26", 
    "2015-12-27", "2015-12-28", "2015-12-29", "2015-12-30", "2015-12-31"
    ), class = "factor"), day_shift = structure(c(1L, 1L, 2L, 2L, 
    3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 
    3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L), .Label = c("A", 
    "B", "C", "D"), class = "factor"), night_shift = structure(c(4L, 
    4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 
    4L, 1L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 1L, 1L, 2L, 2L, 3L), .Label = c("A", 
    "B", "C", "D"), class = "factor")), .Names = c("date", "day_shift", 
    "night_shift"), class = "data.frame", row.names = c(NA, -31L))

In the check data frame, i have the timestamp of each unit produced. by using these timestamp i want to check in which shift the unit is produced.

head(check)
            eventtime
1 2015-12-01 06:10:08
2 2015-12-01 10:10:24
3 2015-12-01 19:01:15
4 2015-12-02 01:54:54
5 2015-12-02 06:24:14
6 2015-12-02 08:15:47

check <- structure(list(eventtime = structure(c(1448946608, 1448961024, 
1448992875, 1449017694, 1449033854, 1449040547, 1449076903, 1449085710, 
1449100168, 1449119720), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = "eventtime", row.names = c(NA, 
-10L), class = "data.frame")

Desired Result:

ds
             eventtime shift
1  2015-12-01 06:10:08     A
2  2015-12-01 10:10:24     A
3  2015-12-01 19:01:15     D
4  2015-12-02 01:54:54     D
5  2015-12-02 06:24:14     A
6  2015-12-02 08:15:47     A
7  2015-12-02 18:21:43     D
8  2015-12-02 20:48:30     D
9  2015-12-03 00:49:28     D
10 2015-12-03 06:15:20     B

To keep it simple, i showed only shifts plan of december month. In reality i need to check the complete year.


Solution

  • Here's an answer using lubridate and its %within% functions to check if a date is within an interval. Depending upon whether your raw data is actually stored as factors or not you can simplify the code by removing some of the conversions.

    library(lubridate)
    
    day_shift_start <- as.POSIXct(shifts$date) + hms("06:00:00")
    day_shift_end <- as.POSIXct(shifts$date) + hms("17:59:59")
    night_shift_start <- as.POSIXct(shifts$date) + hms("18:00:00")
    night_shift_end <- as.POSIXct(shifts$date) + days(1) + hms("05:59:59")
    
    shift_intervals <- data.frame(intervals = c(interval(day_shift_start, day_shift_end),
                                                interval(night_shift_start, night_shift_end)),
                                  shift = c(as.character(shifts$day_shift),
                                            as.character(shifts$night_shift)))
    check$shift <- unlist(lapply(check$eventtime, function(x) {
                      shift_intervals$shift[x %within% shift_intervals$intervals]
                   }))
    
    check
    
    #              eventtime shift
    # 1  2015-12-01 06:10:08     A
    # 2  2015-12-01 10:10:24     A
    # 3  2015-12-01 19:01:15     D
    # 4  2015-12-02 01:54:54     D
    # 5  2015-12-02 06:24:14     A
    # 6  2015-12-02 08:15:47     A
    # 7  2015-12-02 18:21:43     D
    # 8  2015-12-02 20:48:30     D
    # 9  2015-12-03 00:49:28     D
    # 10 2015-12-03 06:15:20     B