如何从 POSIXct 范围子集 POSIXct
how to subset POSIXct from POSIXct range
我在弄清楚如何提取事件的另一个时间(在我的案例字母中)期间发生的事件时间时遇到了问题。我希望有人能帮助我!
简而言之:我想要 bb tibble 的行,其开始或结束或两者(开始和结束)时间在 aa 记录的范围内。
最终目标是找出这些字母在 a a tibble 中出现了多少次。
请让我知道是否需要更多说明!
提前致谢!
aa <- tibble(
start = as.POSIXct(c("2019-05-02 07:08:49", "2019-05-02 07:09:21",
"2019-05-02 07:09:41", "2019-05-02 07:10:05",
"2019-05-02 07:24:52", "2019-05-02 07:28:50",
"2019-05-02 07:29:23", "2019-05-02 07:30:16",
"2019-05-02 07:33:13", "2019-05-02 07:33:43",
"2019-05-02 07:35:31", "2019-05-02 07:36:29",
"2019-05-02 07:38:14", "2019-05-02 07:43:26",
"2019-05-02 07:44:59", "2019-05-02 07:53:45",
"2019-05-02 07:54:28")),
end = as.POSIXct(c("2019-05-02 07:09:29", "2019-05-02 07:10:02",
"2019-05-02 07:10:17", "2019-05-02 07:10:40",
"2019-05-02 07:29:10", "2019-05-02 07:29:32",
"2019-05-02 07:30:35", "2019-05-02 07:30:53",
"2019-05-02 07:33:48", "2019-05-02 07:34:18",
"2019-05-02 07:36:06", "2019-05-02 07:38:34",
"2019-05-02 07:38:49", "2019-05-02 07:45:19",
"2019-05-02 07:45:35", "2019-05-02 07:54:20",
"2019-05-02 07:55:03")))
bb <- tibble(letters = sample(letters[1:4], 12, TRUE),
started = as.POSIXct(c("2019-05-02 07:30:23", "2019-05-02 07:30:56",
"2019-05-02 07:31:29", "2019-05-02 07:31:55",
"2019-05-02 07:32:22", "2019-05-02 07:32:48",
"2019-05-02 07:33:14", "2019-05-02 07:44:36",
"2019-05-02 07:45:11", "2019-05-02 07:45:36",
"2019-05-02 07:46:01", "2019-05-02 07:48:14"
)),
stopped = as.POSIXct(c("2019-05-02 07:30:56", "2019-05-02 07:31:29",
"2019-05-02 07:31:55", "2019-05-02 07:32:22",
"2019-05-02 07:32:48", "2019-05-02 07:33:14",
"2019-05-02 07:33:40", "2019-05-02 07:45:10",
"2019-05-02 07:45:36", "2019-05-02 07:46:01",
"2019-05-02 07:46:25", "2019-05-02 07:48:48")))
这是一种使用 fuzzyjoin 的方法,它允许您指定 bb$started
必须 >= aa$start
,而 bb$stopped <= aa$end
.
library(fuzzyjoin);
fuzzy_inner_join(bb, aa,
by = c("started" = "start",
"stopped" = "end"),
match_fun = list(`>=`, `<=`)
)
# A tibble: 2 x 5
letters started stopped start end
<chr> <dttm> <dttm> <dttm> <dttm>
1 a 2019-05-02 07:33:14 2019-05-02 07:33:40 2019-05-02 07:33:13 2019-05-02 07:33:48
2 c 2019-05-02 07:44:36 2019-05-02 07:45:10 2019-05-02 07:43:26 2019-05-02 07:45:19
data.table 包中有两个函数对此很有用。
最简单的可能是inrange
函数:
使用 inrange
来识别 bb 中开始或停止的行在 aa 中的任何 row-wise start-end 间隔内。
library(data.table)
setDT(bb)
bb[started %inrange% aa | stopped %inrange% aa]
# letters started stopped
# 1: a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 3: c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 4: c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 5: b 2019-05-02 07:45:11 2019-05-02 07:45:36
要获得所需的计数,请按字母和 return 出现次数分组:
bb[started %inrange% aa | stopped %inrange% aa, list(count = .N), by = letters]
# letters count
#1: a 2
#2: c 2
#3: b 1
foverlaps
函数也可以用于此;更灵活但更复杂:
首先在 aa 和 bb 上设置密钥:
setDT(aa)
setkey(aa, start, end)
setDT(bb)
setkey(bb, started, stopped)
对 foverlaps 的简单调用显示了连接的结果,其中 bb 中的行不匹配 aa 中的任何间隔。
foverlaps(aa, bb)
# start end letters started stopped
# 1: 2019-05-02 07:29:23 2019-05-02 07:30:35 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: 2019-05-02 07:30:16 2019-05-02 07:30:53 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 3: <NA> <NA> a 2019-05-02 07:30:56 2019-05-02 07:31:29
# 4: <NA> <NA> b 2019-05-02 07:31:29 2019-05-02 07:31:55
# 5: <NA> <NA> d 2019-05-02 07:31:55 2019-05-02 07:32:22
# 6: <NA> <NA> b 2019-05-02 07:32:22 2019-05-02 07:32:48
# 7: 2019-05-02 07:33:13 2019-05-02 07:33:48 a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 8: 2019-05-02 07:33:13 2019-05-02 07:33:48 c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 9: 2019-05-02 07:43:26 2019-05-02 07:45:19 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 10: 2019-05-02 07:44:59 2019-05-02 07:45:35 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 11: 2019-05-02 07:43:26 2019-05-02 07:45:19 b 2019-05-02 07:45:11 2019-05-02 07:45:36
# 12: 2019-05-02 07:44:59 2019-05-02 07:45:35 b 2019-05-02 07:45:11 2019-05-02 07:45:36
# 13: <NA> <NA> c 2019-05-02 07:45:36 2019-05-02 07:46:01
# 14: <NA> <NA> a 2019-05-02 07:46:01 2019-05-02 07:46:25
# 15: <NA> <NA> c 2019-05-02 07:48:14 2019-05-02 07:48:48
要仅获取 bb 中与 aa 中的间隔匹配的行,请使用 set nomatch
:
foverlaps(bb, aa, nomatch = NULL)
类似地,要只显示每个匹配行一次,请设置 mult
:
foverlaps(bb, aa, nomatch = NULL, mult = "first")
# start end letters started stopped
# 1: 2019-05-02 07:29:23 2019-05-02 07:30:35 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: 2019-05-02 07:33:13 2019-05-02 07:33:48 a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 3: 2019-05-02 07:33:13 2019-05-02 07:33:48 c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 4: 2019-05-02 07:43:26 2019-05-02 07:45:19 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 5: 2019-05-02 07:43:26 2019-05-02 07:45:19 b 2019-05-02 07:45:11 2019-05-02 07:45:36
您可以通过对字母分组并计算行数来计算每个字母的匹配出现次数:
foverlaps(aa, bb, nomatch = NULL, mult = "first")[ , list(count = .N), by = letters]
# letters count
#1: a 2
#2: c 2
#3: b 1
我在弄清楚如何提取事件的另一个时间(在我的案例字母中)期间发生的事件时间时遇到了问题。我希望有人能帮助我! 简而言之:我想要 bb tibble 的行,其开始或结束或两者(开始和结束)时间在 aa 记录的范围内。 最终目标是找出这些字母在 a a tibble 中出现了多少次。 请让我知道是否需要更多说明! 提前致谢!
aa <- tibble(
start = as.POSIXct(c("2019-05-02 07:08:49", "2019-05-02 07:09:21",
"2019-05-02 07:09:41", "2019-05-02 07:10:05",
"2019-05-02 07:24:52", "2019-05-02 07:28:50",
"2019-05-02 07:29:23", "2019-05-02 07:30:16",
"2019-05-02 07:33:13", "2019-05-02 07:33:43",
"2019-05-02 07:35:31", "2019-05-02 07:36:29",
"2019-05-02 07:38:14", "2019-05-02 07:43:26",
"2019-05-02 07:44:59", "2019-05-02 07:53:45",
"2019-05-02 07:54:28")),
end = as.POSIXct(c("2019-05-02 07:09:29", "2019-05-02 07:10:02",
"2019-05-02 07:10:17", "2019-05-02 07:10:40",
"2019-05-02 07:29:10", "2019-05-02 07:29:32",
"2019-05-02 07:30:35", "2019-05-02 07:30:53",
"2019-05-02 07:33:48", "2019-05-02 07:34:18",
"2019-05-02 07:36:06", "2019-05-02 07:38:34",
"2019-05-02 07:38:49", "2019-05-02 07:45:19",
"2019-05-02 07:45:35", "2019-05-02 07:54:20",
"2019-05-02 07:55:03")))
bb <- tibble(letters = sample(letters[1:4], 12, TRUE),
started = as.POSIXct(c("2019-05-02 07:30:23", "2019-05-02 07:30:56",
"2019-05-02 07:31:29", "2019-05-02 07:31:55",
"2019-05-02 07:32:22", "2019-05-02 07:32:48",
"2019-05-02 07:33:14", "2019-05-02 07:44:36",
"2019-05-02 07:45:11", "2019-05-02 07:45:36",
"2019-05-02 07:46:01", "2019-05-02 07:48:14"
)),
stopped = as.POSIXct(c("2019-05-02 07:30:56", "2019-05-02 07:31:29",
"2019-05-02 07:31:55", "2019-05-02 07:32:22",
"2019-05-02 07:32:48", "2019-05-02 07:33:14",
"2019-05-02 07:33:40", "2019-05-02 07:45:10",
"2019-05-02 07:45:36", "2019-05-02 07:46:01",
"2019-05-02 07:46:25", "2019-05-02 07:48:48")))
这是一种使用 fuzzyjoin 的方法,它允许您指定 bb$started
必须 >= aa$start
,而 bb$stopped <= aa$end
.
library(fuzzyjoin);
fuzzy_inner_join(bb, aa,
by = c("started" = "start",
"stopped" = "end"),
match_fun = list(`>=`, `<=`)
)
# A tibble: 2 x 5
letters started stopped start end
<chr> <dttm> <dttm> <dttm> <dttm>
1 a 2019-05-02 07:33:14 2019-05-02 07:33:40 2019-05-02 07:33:13 2019-05-02 07:33:48
2 c 2019-05-02 07:44:36 2019-05-02 07:45:10 2019-05-02 07:43:26 2019-05-02 07:45:19
data.table 包中有两个函数对此很有用。
最简单的可能是inrange
函数:
使用 inrange
来识别 bb 中开始或停止的行在 aa 中的任何 row-wise start-end 间隔内。
library(data.table)
setDT(bb)
bb[started %inrange% aa | stopped %inrange% aa]
# letters started stopped
# 1: a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 3: c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 4: c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 5: b 2019-05-02 07:45:11 2019-05-02 07:45:36
要获得所需的计数,请按字母和 return 出现次数分组:
bb[started %inrange% aa | stopped %inrange% aa, list(count = .N), by = letters]
# letters count
#1: a 2
#2: c 2
#3: b 1
foverlaps
函数也可以用于此;更灵活但更复杂:
首先在 aa 和 bb 上设置密钥:
setDT(aa)
setkey(aa, start, end)
setDT(bb)
setkey(bb, started, stopped)
对 foverlaps 的简单调用显示了连接的结果,其中 bb 中的行不匹配 aa 中的任何间隔。
foverlaps(aa, bb)
# start end letters started stopped
# 1: 2019-05-02 07:29:23 2019-05-02 07:30:35 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: 2019-05-02 07:30:16 2019-05-02 07:30:53 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 3: <NA> <NA> a 2019-05-02 07:30:56 2019-05-02 07:31:29
# 4: <NA> <NA> b 2019-05-02 07:31:29 2019-05-02 07:31:55
# 5: <NA> <NA> d 2019-05-02 07:31:55 2019-05-02 07:32:22
# 6: <NA> <NA> b 2019-05-02 07:32:22 2019-05-02 07:32:48
# 7: 2019-05-02 07:33:13 2019-05-02 07:33:48 a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 8: 2019-05-02 07:33:13 2019-05-02 07:33:48 c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 9: 2019-05-02 07:43:26 2019-05-02 07:45:19 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 10: 2019-05-02 07:44:59 2019-05-02 07:45:35 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 11: 2019-05-02 07:43:26 2019-05-02 07:45:19 b 2019-05-02 07:45:11 2019-05-02 07:45:36
# 12: 2019-05-02 07:44:59 2019-05-02 07:45:35 b 2019-05-02 07:45:11 2019-05-02 07:45:36
# 13: <NA> <NA> c 2019-05-02 07:45:36 2019-05-02 07:46:01
# 14: <NA> <NA> a 2019-05-02 07:46:01 2019-05-02 07:46:25
# 15: <NA> <NA> c 2019-05-02 07:48:14 2019-05-02 07:48:48
要仅获取 bb 中与 aa 中的间隔匹配的行,请使用 set nomatch
:
foverlaps(bb, aa, nomatch = NULL)
类似地,要只显示每个匹配行一次,请设置 mult
:
foverlaps(bb, aa, nomatch = NULL, mult = "first")
# start end letters started stopped
# 1: 2019-05-02 07:29:23 2019-05-02 07:30:35 a 2019-05-02 07:30:23 2019-05-02 07:30:56
# 2: 2019-05-02 07:33:13 2019-05-02 07:33:48 a 2019-05-02 07:32:48 2019-05-02 07:33:14
# 3: 2019-05-02 07:33:13 2019-05-02 07:33:48 c 2019-05-02 07:33:14 2019-05-02 07:33:40
# 4: 2019-05-02 07:43:26 2019-05-02 07:45:19 c 2019-05-02 07:44:36 2019-05-02 07:45:10
# 5: 2019-05-02 07:43:26 2019-05-02 07:45:19 b 2019-05-02 07:45:11 2019-05-02 07:45:36
您可以通过对字母分组并计算行数来计算每个字母的匹配出现次数:
foverlaps(aa, bb, nomatch = NULL, mult = "first")[ , list(count = .N), by = letters]
# letters count
#1: a 2
#2: c 2
#3: b 1