r - 满足条件的连续事件之间的R间隔 - data.table方式
问题描述
我有一个连续事件的数据集,按 id 分组并按事件开始日期(开始)排序。每个事件可以有 2 个状态 (cond),a 和 b。我需要计算 2 个 CONSECUTIVE 事件(开始 - 结束)之间的间隔,但前提是较新的事件符合某个标准:cond !="b"。如果不是,则该事件的 interval=NA 并移至下一个。这是一个玩具数据集:
dt=data.table(stringsAsFactors=FALSE,
id = c(111, 111, 111, 111, 222, 222, 222, 222, 333, 333, 333, 333),
cond=c("a", "a", "a", "a", "a", "b", "a", "a", "a", "b", "b", "b"),
start = c(as.Date( "11/19/2020", format="%m/%d/%Y"),as.Date( "11/27/2020", format="%m/%d/%Y"),as.Date( "12/5/2020", format="%m/%d/%Y"),as.Date( "12/13/2020", format="%m/%d/%Y"),as.Date( "12/21/2020", format="%m/%d/%Y"),as.Date( "12/29/2020", format="%m/%d/%Y"),as.Date( "1/6/2021", format="%m/%d/%Y"),as.Date( "1/14/2021", format="%m/%d/%Y"),as.Date( "1/22/2021", format="%m/%d/%Y"),as.Date( "1/30/2021", format="%m/%d/%Y"),as.Date( "2/7/2021", format="%m/%d/%Y"),as.Date( "2/15/2021", format="%m/%d/%Y")),
end = c(as.Date( "11/24/2020", format="%m/%d/%Y"),as.Date( "12/2/2020", format="%m/%d/%Y"),as.Date( "12/10/2020", format="%m/%d/%Y"),as.Date( "12/18/2020", format="%m/%d/%Y"),as.Date( "12/26/2020", format="%m/%d/%Y"),as.Date( "1/3/2021", format="%m/%d/%Y"),as.Date( "1/11/2021", format="%m/%d/%Y"),as.Date( "1/19/2021", format="%m/%d/%Y"),as.Date( "1/27/2021", format="%m/%d/%Y"),as.Date( "2/4/2021", format="%m/%d/%Y"),as.Date( "2/12/2021", format="%m/%d/%Y"),as.Date( "2/20/2021", format="%m/%d/%Y")
))
结果应如下所示:
id cond start end interval
1 111 a 11/19/2020 11/24/2020 3
2 111 a 11/27/2020 12/2/2020 3
3 111 a 12/5/2020 12/10/2020 3
4 111 a 12/13/2020 12/18/2020 NA
5 222 a 12/21/2020 12/26/2020 NA
6 222 b 12/29/2020 1/3/2021 3
7 222 a 1/6/2021 1/11/2021 3
8 222 a 1/14/2021 1/19/2021 NA
9 333 a 1/22/2021 1/27/2021 NA
10 333 b 1/30/2021 2/4/2021 NA
11 333 b 2/7/2021 2/12/2021 NA
12 333 b 2/15/2021 2/20/2021 NA
因此,条件 cond!="b" 仅适用于“开始”行;我希望这样的事情会起作用:
dt[,interval:= shift(start[cond!="b"],n = 1L,type="lead") -end ,id]
但事实并非如此。我也尝试过滚动连接:
dt[,row_id:=rowid(id)]
dt[, interval :=
.SD[.(cond!="b", id = id, row_id = row_id +1), on=.(id,row_id), roll=-Inf, x.start]-end]
这也不能满足我的需要。我觉得 data.table 应该能够很容易地处理这个任务。我只是不知道怎么做。任何帮助将不胜感激。
解决方案
要获得价值,您可以从每个日期interval
中减去下一个start
日期。将所有值转到下一个值所在的位置。end
id
interval
NA
cond
'b'
library(data.table)
dt[, interval := as.integer(shift(start, type = 'lead') - end), id]
dt[shift(cond, type = 'lead') == 'b', interval := NA]
dt
# id cond start end interval
# 1: 111 a 2020-11-19 2020-11-24 3
# 2: 111 a 2020-11-27 2020-12-02 3
# 3: 111 a 2020-12-05 2020-12-10 3
# 4: 111 a 2020-12-13 2020-12-18 NA
# 5: 222 a 2020-12-21 2020-12-26 NA
# 6: 222 b 2020-12-29 2021-01-03 3
# 7: 222 a 2021-01-06 2021-01-11 3
# 8: 222 a 2021-01-14 2021-01-19 NA
# 9: 333 a 2021-01-22 2021-01-27 NA
#10: 333 b 2021-01-30 2021-02-04 NA
#11: 333 b 2021-02-07 2021-02-12 NA
#12: 333 b 2021-02-15 2021-02-20 NA
推荐阅读
- elixir - 如何在嵌套变更集上使用 add_error?
- laravel - Laravel 分页和 Orderby
- ios - 仅为新文件启用 SwiftLint
- blockchain - 使用 Ganache 提供的地址但仍然无法投票
- mysql - MySQL:服务已关闭 || Zabbix 代理 ubuntu
- c# - 当我的 mongoDB 尝试与 KLOV 连接以生成测试执行报告时,我遇到了异常
- arduino - 定义传感器属性
- informatica-powercenter - 错误消息节点日志 Informatica PowerCenter
- javascript - 如何在 webrtc 中实时流数据
- javascript - 静态站点生成器、mvc、laravel 或 plain 包括...使用什么