LaVOZs

The World’s Largest Online Community for Developers

'; r - How to get people in the store at every 5 minutes? - LavOzs.Com

I have a data table like below :

library(data.table)
DT1<-data.table(
  id=c(1,2,3,4,3,2),
  in_time=c("2017-11-01 08:37:35","2017-11-01 09:07:44","2017-11-01 09:46:16","2017-11-01 10:32:29","2017-11-01 10:59:25","2017-11-01 13:24:12"),
  out_time=c("2017-11-01 08:45:35","2017-11-01 09:15:30","2017-11-01 10:11:16","2017-11-01 10:37:05","2017-11-01 11:45:25","2017-11-01 14:10:09")
  )

It contains each information about what time a person enters the store and exits the store.

Now I want to take the people in the store every 5 minutes (standard 5 minutes like minute 0,5,10,15 ...60). If there is no one I need a 0 value.

So I tried with

library(lubridate)
DT1[,time:=ymd_hms(in_time)]
DT1[,time:=ceiling_date(time,"5mins")]
DT1[,.N,by=list(time)]

which only gives how many people entered at each time but I am now stuck at how to take into account the out_time.For example, the id 1 entered at 2017-11-01 08:37:35 and left at 2017-11-01 08:45:35.So he will be in the shop for the 5-minute interval from 2017-11-01 08:40:00 to 2017-11-01 08:45:00 and not in 2017-11-01 08:50:00 and so on .

An id can repeat multiple times like one person came drop by the store multiple times a day.

Any help is appreciated .

Here is an option using data.table::foverlaps:

#generate intervals of 5mins
times <- seq(as.POSIXct("2017-11-01 00:00:00", format=fmt), 
    as.POSIXct("2017-11-02 00:00:00", format=fmt), 
    by="5 min")
DT2 <- data.table(in_time=times[-length(times)], out_time=times[-1L], key=c("in_time","out_time"))

#set keys before foverlaps
setkey(DT1, in_time, out_time)

#find overlaps and count distinct in each 5min interval. 
#!is.na(id) is for truncating the output for checking. to be removed in actual code 
foverlaps(DT2, DT1)[!is.na(id), uniqueN(id), .(i.in_time, i.out_time)]

And if id is unique in each time interval, the last line of code can be foverlaps(DT2, DT1)[, sum(!is.na(id)), .(i.in_time, i.out_time)] instead

first 8 rows of output:

              i.in_time          i.out_time V1
 1: 2017-11-01 08:35:00 2017-11-01 08:40:00  1
 2: 2017-11-01 08:40:00 2017-11-01 08:45:00  1
 3: 2017-11-01 08:45:00 2017-11-01 08:50:00  1
 4: 2017-11-01 09:05:00 2017-11-01 09:10:00  1
 5: 2017-11-01 09:10:00 2017-11-01 09:15:00  1
 6: 2017-11-01 09:15:00 2017-11-01 09:20:00  1
 7: 2017-11-01 09:45:00 2017-11-01 09:50:00  1
 8: 2017-11-01 09:50:00 2017-11-01 09:55:00  1

data:

library(data.table)
DT1 <- data.table(
    id=c(1,2,3,4,3,2),
    in_time=c("2017-11-01 08:37:35","2017-11-01 09:07:44","2017-11-01 09:46:16","2017-11-01 10:32:29","2017-11-01 10:59:25","2017-11-01 13:24:12"),
    out_time=c("2017-11-01 08:45:35","2017-11-01 09:15:30","2017-11-01 10:11:16","2017-11-01 10:37:05","2017-11-01 11:45:25","2017-11-01 14:10:09")
)
cols <- c("in_time", "out_time")
fmt <- "%Y-%m-%d %T"
DT1[, (cols) := lapply(.SD, as.POSIXct, format=fmt), .SDcols=cols]
Related