[英]Find events between time frames using data.table R
如果徒步旅行者正在访问,我有一个小屋的数据表。
library(data.table)
dt <- data.table(time = as.POSIXct(as.Date(10:35, origin = "2020-01-01")),
hut= c(1, NA, NA, 8, 1, 1, NA, NA, NA, 1, NA, NA, NA,
4, NA, NA, 4, NA, 5, NA, NA, 4, NA, 4, NA, 1))
这种模式是它们将从野外的小屋(例如小屋 1)迁出(小屋 = NA)并在 2-5 天内回来。 这是一个事件。 有时他们会去一个新的小屋(例如小屋 4)——这不是一个事件。 问题是有时他们会意外地在事件中的小屋中(如第 4 行)。 所以这仍然是一个事件。 输出应该是这样的,但我不知道如何得到它。 真正的数据是数十亿行,所以它也应该是高效的,因此 data.table:
dt[, event:= c(NA, 1,1,1, NA, NA, 2,2,2,
NA, NA,NA, NA, NA,
3,3, NA, 4,4,4,4,NA, 5, NA,NA, NA)]
dt
time hut event
1: 2020-01-11 01:00:00 1 NA
2: 2020-01-12 01:00:00 NA 1
3: 2020-01-13 01:00:00 NA 1
4: 2020-01-14 01:00:00 8 1
5: 2020-01-15 01:00:00 1 NA
6: 2020-01-16 01:00:00 1 NA
7: 2020-01-17 01:00:00 NA 2
8: 2020-01-18 01:00:00 NA 2
9: 2020-01-19 01:00:00 NA 2
10: 2020-01-20 01:00:00 1 NA
11: 2020-01-21 01:00:00 NA NA
12: 2020-01-22 01:00:00 NA NA
13: 2020-01-23 01:00:00 NA NA
14: 2020-01-24 01:00:00 4 NA
15: 2020-01-25 01:00:00 NA 3
16: 2020-01-26 01:00:00 NA 3
17: 2020-01-27 01:00:00 4 NA
18: 2020-01-28 01:00:00 NA 4
19: 2020-01-29 01:00:00 5 4
20: 2020-01-30 01:00:00 NA 4
21: 2020-01-31 01:00:00 NA 4
22: 2020-02-01 01:00:00 4 NA
23: 2020-02-02 01:00:00 NA 5
24: 2020-02-03 01:00:00 4 NA
25: 2020-02-04 01:00:00 NA NA
26: 2020-02-05 01:00:00 1 NA
这是使用非对等连接的另一种选择:
dt[, rn := .I]
visits <- dt[!is.na(hut)]
visits[, c("start", "end") := .(time + 2L, time + 5L)]
rows <- visits[visits, on=.(hut, time>=start, time<=end), mult="first", nomatch=0L,
.(hut, i.time, x.time, i.rn, x.rn)]
dt[rows, on=.(rn>i.rn, rn<x.rn), event := 1L]
dt[, ri := rleid(event)][!is.na(event), event := rleid(ri)]
dt[rn %in% unique(c(rows$i.rn, rows$x.rn)), event := NA_integer_]
dt[, c("ri", "rn") := NULL][]
输出:
time hut event
1: 2020-01-11 1 NA
2: 2020-01-12 NA 1
3: 2020-01-13 NA 1
4: 2020-01-14 8 1
5: 2020-01-15 1 NA
6: 2020-01-16 1 NA
7: 2020-01-17 NA 2
8: 2020-01-18 NA 2
9: 2020-01-19 NA 2
10: 2020-01-20 1 NA
11: 2020-01-21 NA NA
12: 2020-01-22 NA NA
13: 2020-01-23 NA NA
14: 2020-01-24 4 NA
15: 2020-01-25 NA 3
16: 2020-01-26 NA 3
17: 2020-01-27 4 NA
18: 2020-01-28 NA 4
19: 2020-01-29 5 4
20: 2020-01-30 NA 4
21: 2020-01-31 NA 4
22: 2020-02-01 4 NA
23: 2020-02-02 NA 5
24: 2020-02-03 4 NA
25: 2020-02-04 NA NA
26: 2020-02-05 1 NA
time hut event
或者,使用滚动连接而不是上面的非等连接:
is <- 2L
intvl <- 5L - is
dt[, c("rn", "oned") := .(.I, time + is)]
rows <- dt[dt[!is.na(hut)], on=.(hut, time=oned), roll=-intvl, nomatch=0L,
.(hut, i.rn, x.rn)]
#the rest of the code from the non-equi join above is needed here as well
数据:
library(data.table)
dt <- data.table(time = as.Date(10:35, origin = "2020-01-01"),
hut= c(1, NA, NA, 8, 1, 1, NA, NA, NA, 1, NA, NA, NA,
4, NA, NA, 4, NA, 5, NA, NA, 4, NA, 4, NA, 1))
好吧,这不是很明显,但让我们尝试..
library(data.table)
dt <- data.table(time = as.POSIXct(as.Date(10:35, origin = "2020-01-01")),
hut= c(1, NA, NA, 8, 1, 1, NA, NA, NA, 1, NA, NA, NA,
4, NA, NA, 4, NA, 5, NA, NA, 4, NA, 4, NA, 1))
library(dplyr)
dt[, last.hut1 := lag(hut, n = 1, order_by = time)]
dt[, last.hut2 := lag(hut, n = 2, order_by = time)]
dt[, last.hut3 := lag(hut, n = 3, order_by = time)]
dt[, last.hut4 := lag(hut, n = 4, order_by = time)]
dt[, last.hut5 := lag(hut, n = 5, order_by = time)]
dt[, next.hut1 := lead(hut, n = 1, order_by = time)]
dt[, next.hut2 := lead(hut, n = 2, order_by = time)]
dt[, next.hut3 := lead(hut, n = 3, order_by = time)]
dt[, next.hut4 := lead(hut, n = 4, order_by = time)]
dt[, next.hut5 := lead(hut, n = 5, order_by = time)]
dt[, end.event := case_when((hut == last.hut2 | hut == last.hut3 | hut == last.hut4 | hut == last.hut5)
& (last.hut1 != hut | is.na(last.hut1)) ~ 1,
TRUE ~ 0)]
dt[, start.event := case_when((hut == next.hut2 | hut == next.hut3 | hut == next.hut4 | hut == next.hut5)
& (next.hut1 != hut | is.na(next.hut1)) ~ 1,
TRUE ~ 0)]
dt[, start.event2 := cumsum(start.event)]
dt[, end.event2 := cumsum(end.event)]
dt[, event := case_when((start.event2 > end.event2) & (start.event == 0) & (end.event == 0) ~ start.event2,
TRUE ~ NA_real_)]
dt[ ,c("last.hut1", "last.hut2", "last.hut3", "last.hut4", "last.hut5",
"next.hut1", "next.hut2", "next.hut3", "next.hut4", "next.hut5",
"start.event", "start.event2", "end.event", "end.event2") := .(NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.