r - 根据 R 中 30 分钟或更长的时间差识别离散事件
问题描述
当在特定位置检测到单个动物 (ID) 时,我有一个时间戳数据框。以下是数据示例:
timestampUTC location ID
2017-10-02 19:23:27 JB12 A69-1601-47272
2017-10-02 19:26:48 JB12 A69-1601-47272
2017-10-02 19:27:23 JB12 A69-1601-47272
2017-10-02 19:31:46 JB12 A69-1601-47272
2017-10-02 23:52:15 JB12 A69-1601-47272
2017-10-02 23:53:26 JB12 A69-1601-47272
2017-10-02 23:55:13 JB12 A69-1601-47272
2017-10-03 19:53:50 JB13 A69-1601-47272
2017-10-03 19:55:23 JB13 A69-1601-47272
2017-10-03 19:58:26 JB13 A69-1601-47272
2017-10-04 13:15:13 JB12 A69-1601-47280
2017-10-04 13:16:42 JB12 A69-1601-47280
2017-10-04 13:21:39 JB12 A69-1601-47280
2017-10-04 19:34:54 JB12 A69-1601-47280
2017-10-04 19:55:28 JB12 A69-1601-47280
2017-10-04 20:08:23 JB12 A69-1601-47280
2017-10-04 20:21:43 JB12 A69-1601-47280
2017-10-05 04:55:48 JB13 A69-1601-47280
2017-10-05 04:57:04 JB13 A69-1601-47280
2017-10-05 05:18:40 JB13 A69-1601-47280
2017-10-07 21:24:19 JB13 A69-1601-47280
2017-10-07 21:25:36 JB13 A69-1601-47280
2017-10-07 21:29:25 JB13 A69-1601-47280
我的真实数据框有将近 200,000 行长,有 4 个不同的位置和 13 个不同的 ID。
我想根据 timestampUTC 列将这些事件分类为具有开始和结束时间的离散事件(位置 ID),当在该位置对该 ID 的下一次检测超过半小时后,事件以时间戳UTC 结束。下一个事件在下一个日期时间开始。
使用上面的示例数据,我想生成另一个看起来像这样的数据框:
ID location event start event end
A69-1601-47272 JB12 2017-10-02 19:23:27 2017-10-02 19:31:46
A69-1601-47272 JB12 2017-10-02 23:52:15 2017-10-02 23:55:13
A69-1601-47272 JB13 2017-10-03 19:53:50 2017-10-03 19:58:26
A69-1601-47280 JB12 2017-10-04 13:15:13 2017-10-04 13:21:39
A69-1601-47280 JB12 2017-10-04 19:34:54 2017-10-04 20:21:43
A69-1601-47280 JB13 2017-10-05 04:55:48 2017-10-05 05:18:40
A69-1601-47280 JB13 2017-10-07 21:24:19 2017-10-07 21:29:25
如果在某个位置检测到 ID,它会给出 ID、位置以及该位置的开始和结束时间。
例如,您可以看到在同一天 (2017-10-02) 发生在位置 JB12 的 ID 47272 的 2 个离散事件,但第一个事件的结束和第二个事件的开始之间的差异 >30分钟(约 4 小时 20 分钟),因此它们是单独的事件。
我会添加我尝试过的代码,但我不知道从哪里开始。
提前致谢!
解决方案
这是一个选项
library(tidyverse)
df %>%
mutate(
timestampUTC = as.POSIXct(timestampUTC),
diff = c(0, diff(timestampUTC) / 60),
grp = cumsum(diff > 30)) %>%
group_by(grp) %>%
summarise(
ID = first(ID),
location = first(location),
`event start` = first(timestampUTC),
`event end` = last(timestampUTC))
## A tibble: 7 x 5
# grp ID location `event start` `event end`
# <int> <fct> <fct> <dttm> <dttm>
#1 0 A69-1601-47272 JB12 2017-10-02 19:23:27 2017-10-02 19:31:46
#2 1 A69-1601-47272 JB12 2017-10-02 23:52:15 2017-10-02 23:55:13
#3 2 A69-1601-47272 JB13 2017-10-03 19:53:50 2017-10-03 19:58:26
#4 3 A69-1601-47280 JB12 2017-10-04 13:15:13 2017-10-04 13:21:39
#5 4 A69-1601-47280 JB12 2017-10-04 19:34:54 2017-10-04 20:21:43
#6 5 A69-1601-47280 JB13 2017-10-05 04:55:48 2017-10-05 05:18:40
#7 6 A69-1601-47280 JB13 2017-10-07 21:24:19 2017-10-07 21:29:25
我保留了一些中间步骤(列)以帮助提高可读性和理解性。简而言之,我们将时间戳转换为POSIXct
,然后用 计算连续时间戳之间的时间差(以分钟为diff
单位),根据下一个时间戳是否在> 30
几分钟之外创建观察组。剩下的就是对grp
相关列中的条目进行分组和汇总。
一样,更简洁(也许以牺牲可读性为代价)
df %>%
group_by(grp = cumsum(c(0, diff(as.POSIXct(timestampUTC)) / 60) > 30)) %>%
summarise(
ID = first(ID),
location = first(location),
`event start` = first(timestampUTC),
`event end` = last(timestampUTC)) %>%
select(-grp)
样本数据
df <- read.table(text =
"timestampUTC location ID
'2017-10-02 19:23:27' JB12 A69-1601-47272
'2017-10-02 19:26:48' JB12 A69-1601-47272
'2017-10-02 19:27:23' JB12 A69-1601-47272
'2017-10-02 19:31:46' JB12 A69-1601-47272
'2017-10-02 23:52:15' JB12 A69-1601-47272
'2017-10-02 23:53:26' JB12 A69-1601-47272
'2017-10-02 23:55:13' JB12 A69-1601-47272
'2017-10-03 19:53:50' JB13 A69-1601-47272
'2017-10-03 19:55:23' JB13 A69-1601-47272
'2017-10-03 19:58:26' JB13 A69-1601-47272
'2017-10-04 13:15:13' JB12 A69-1601-47280
'2017-10-04 13:16:42' JB12 A69-1601-47280
'2017-10-04 13:21:39' JB12 A69-1601-47280
'2017-10-04 19:34:54' JB12 A69-1601-47280
'2017-10-04 19:55:28' JB12 A69-1601-47280
'2017-10-04 20:08:23' JB12 A69-1601-47280
'2017-10-04 20:21:43' JB12 A69-1601-47280
'2017-10-05 04:55:48' JB13 A69-1601-47280
'2017-10-05 04:57:04' JB13 A69-1601-47280
'2017-10-05 05:18:40' JB13 A69-1601-47280
'2017-10-07 21:24:19' JB13 A69-1601-47280
'2017-10-07 21:25:36' JB13 A69-1601-47280
'2017-10-07 21:29:25' JB13 A69-1601-47280", header = T)
推荐阅读
- php - 从 .xlsx (Excel) 文件中读取数据并在数组中排列/管理或创建数组
- c# - string[] 数组返回“对象引用未设置为对象实例”的错误。
- php - 反序列化函数没有返回相同格式的返回字符串
- android - 如何在 FAB 点击的单独活动中显示收藏的内容?
- python-3.x - 为项目结构配置 circleci
- python - 如何修复这个 Text.get()?
- google-analytics - 使用谷歌分析从另一个网站获取数据
- python - 将整数值分解为保持总和的整数数组
- telegram - 预先填写的消息到电报号码
- python - facebook.GraphAPIError: (#100) 参数不匹配任何可以更新的字段