在每组数据集中查找重叠时间

时间:2019-07-29 17:50:04

标签: r dataframe

我有“住户”列,“每个住户中的人”,“游览”(每个游览包含每个人的不同旅程)和“方式”(每个游览中每个人的旅行方式),time_ARR游览开始时间,time_Dep结束时间游览。

我想找到一个关于有汽车模式的人和有非汽车模式的人的指标。

如果游览时间与有家庭模式汽车的人相交,则对于游览中具有非汽车模式的每个人,该指标为1。

下面是清楚说明的示例:

  family    persons    mode    tour   start time    end time
     1      1           car     1        2:30         15:30
     1      1         non-car   2        20:00        8:30
     1      2         non-car   1        3:00         10:00
     1      3           car     1        19:10        24:00
     2      1         non-car   1        3:00         10:00
     2      2           car     1        19:10        24:00

在第一个家庭成员1中,他的第二次游览具有非汽车模式,并且与第三人称交叉。

第一家庭中的第二人称2也具有非汽车模式,并且在他的第一次旅行中她也与第一人称交叉。

在第二家庭人1中,

具有非汽车模式,并且不与其他人的汽车模式相交。

  family    persons    mode    tour   start time    end time. indicator
     1      1           car     1        2:30         15:30.      NA
     1      1         non-car   2        20:00        8:30.       1
     1      2         non-car   1        3:00         10:00.      1 
     1      3           car     1        19:10        24:00.      NA
     2      1         non-car   1        3:00         10:00.      0
     2      2           car     1        19:10        24:00.      NA

它不是NA而是0或1,根本没有关系

1 个答案:

答案 0 :(得分:1)

一种查看方式是使用data.table::foverlaps,并将时间作为重叠事件。

准备数据

dat <- read.table(header = TRUE, stringsAsFactors = FALSE, text = "
  family    persons    mode    tour   starttime    endtime
     1      1           car     1        2:30         15:30
     1      1         non-car   2        20:00        8:30
     1      2         non-car   1        3:00         10:00
     1      3           car     1        19:10        24:00
     2      1         non-car   1        3:00         10:00
     2      2           car     1        19:10        24:00")
library(data.table)
setDT(dat)

# convert to actual timestamps ... might also use lubridate or hms packages
dat[, c("starttime", "endtime") := lapply(.(starttime, endtime), as.POSIXct, format = "%H:%M") ]
# assign a simple per-row id
dat[, rowid := seq_len(.N)]

不幸的是,由于您仅在示例数据中列出了时间,因此发生了向后事件,因此我将endtime更改为“明天”:

dat[starttime > endtime,]
#    family persons    mode tour           starttime             endtime rowid
# 1:      1       1 non-car    2 2019-07-29 20:00:00 2019-07-29 08:30:00     2
dat[starttime > endtime, endtime := endtime + 86400 ]

模糊重叠

setkey(dat, starttime, endtime)
merged <- foverlaps(dat[,.(rowid,mode,starttime,endtime)], dat[,.(rowid,mode,starttime,endtime)])
merged[ mode == "car" & i.mode != "car", ]
#    rowid mode           starttime             endtime i.rowid  i.mode         i.starttime           i.endtime
# 1:     1  car 2019-07-29 02:30:00 2019-07-29 15:30:00       3 non-car 2019-07-29 03:00:00 2019-07-29 10:00:00
# 2:     1  car 2019-07-29 02:30:00 2019-07-29 15:30:00       5 non-car 2019-07-29 03:00:00 2019-07-29 10:00:00
# 3:     4  car 2019-07-29 19:10:00 2019-07-30 00:00:00       2 non-car 2019-07-29 20:00:00 2019-07-30 08:30:00
# 4:     6  car 2019-07-29 19:10:00 2019-07-30 00:00:00       2 non-car 2019-07-29 20:00:00 2019-07-30 08:30:00

要摆脱的主旨是,i.rowid表示“第二人称”是"non-car",而第一人称是"car"。由此,很容易确定

# non-car people without a "car" complement
setdiff(dat$rowid, merged[ mode == "car" & i.mode != "car", ]$i.rowid)
# [1] 1 4 6

# non-car people with a car complement
unique(merged[ mode == "car" & i.mode != "car", ]$i.rowid)
# [1] 3 5 2

# non-car people might be able to use these car people
merged[ mode == "car" & i.mode != "car", ][, .(hascar = rowid, needscar = i.rowid)]
#    hascar needscar
# 1:      1        3
# 2:      1        5
# 3:      4        2
# 4:      6        2