如何对顺序事件时间序列(事件之间有中断)进行分组以查找事件的持续时间
How to group sequential event time sequences (with breaks between events) to find duration of events
我在 R 中有一个数据集,其中包含一系列人物、发生的事件以及它们发生的指定时间(以秒为单位,从 0 开始)。它看起来类似于:
event seconds person
1 0.0 Bob
2 15.0 Bob
3 28.5 Bob
4 32.0 Joe
5 38.0 Joe
6 41.0 Joe
7 42.5 Joe
8 55.0 Anne
9 58.0 Anne
我需要对每个名字进行过滤,这意味着为每个人排序的事件不会按顺序排列。
这看起来像一个例子(注意鲍勃如何不参与事件 4-40 等):
event seconds person
1 0.0 Bob
2 15.0 Bob
3 28.5 Bob
41 256.0 Bob
42 261.0 Bob
43 266.0 Bob
44 268.5 Bob
45 272.0 Bob
46 273.0 Bob
49 569.0 Bob
80 570.5 Bob
81 581.0 Bob
顺序相关的事件以1为增量分隔。我想找到相关事件的持续时间,例如事件1-3是一组,即28.5秒。事件 41-46 是另一组,持续 17 秒。这对于人员列中列出的所有姓名都是必需的。
我尝试使用 dplyr 过滤名称,然后使用 as.matrix 找出事件行之间的差异,并确定增量大于 1 的位置(表明它不再是当前事件序列的一部分) ).我还没有找到一种方法来根据此分配最大值和最小值来确定相关事件的持续时间。虽然解决方案不需要涉及此步骤,但这是我能想到的最接近的步骤。
最终目标是绘制每个人的非连续持续时间,以便直观地表示每个人对整个数据集的事件参与情况。
提前谢谢你。
使用这个:
DF <- read.table(text = "event seconds person
1 0.0 Bob
2 15.0 Bob
3 28.5 Bob
41 256.0 Bob
42 261.0 Bob
43 266.0 Bob
44 268.5 Bob
45 272.0 Bob
46 273.0 Bob
49 569.0 Bob
80 570.5 Bob
81 581.0 Bob", header = TRUE)
DF$personEvent <- cumsum(c(1L, diff(DF$event)) != 1L)
# event seconds person personEvent
#1 1 0.0 Bob 0
#2 2 15.0 Bob 0
#3 3 28.5 Bob 0
#4 41 256.0 Bob 1
#5 42 261.0 Bob 1
#6 43 266.0 Bob 1
#7 44 268.5 Bob 1
#8 45 272.0 Bob 1
#9 46 273.0 Bob 1
#10 49 569.0 Bob 2
#11 80 570.5 Bob 3
#12 81 581.0 Bob 3
既然我不是大烟斗的追随者,剩下的就交给你了。
假设首先我们只有 Bob 的数据框行,称为 bob
。
我们假设 bob
已经由 event
订购,递增。
按照您提到的相同思路(查看 diff(event) > 1
),您还可以使用 cumsum
将每个事件分组到它所属的 'run' 个事件中:
library(plyr)
bob2 <- mutate(bob, start = c(1, diff(bob$event) > 1), run=cumsum(start))
event seconds person start run
1 1 0.0 Bob 1 1
2 2 15.0 Bob 0 1
3 3 28.5 Bob 0 1
4 41 256.0 Bob 1 2
5 42 261.0 Bob 0 2
6 43 266.0 Bob 0 2
7 44 268.5 Bob 0 2
8 45 272.0 Bob 0 2
9 46 273.0 Bob 0 2
10 49 569.0 Bob 1 3
11 80 570.5 Bob 1 4
12 81 581.0 Bob 0 4
start
表示这是否启动了 运行 个连续事件,run
是我们所处的事件集。
那么你就可以找到持续时间:
ddply(bob2, .(run), summarize, length=diff(range(seconds)))
run length
1 1 28.5
2 2 17.0
3 3 0.0
4 4 10.5
现在假设你有原始数据框,每个人都混合在一起,我们可以再次使用 ddply
将其按人拆分:
tmp <- ddply(df, .(person), transform, run=cumsum(c(1, diff(event) != 1)))
ddply(tmp, .(person, run), summarize, length=diff(range(seconds)), start_event=first(event), end_event=last(event))
person run length start_event end_event
1 Anne 1 3.0 8 9
2 Bob 1 28.5 1 3
3 Bob 2 17.0 41 46
4 Bob 3 0.0 49 49
5 Bob 4 10.5 80 81
6 Joe 1 10.5 4 7
注意:我的 df
是你的 bob table rbind-ed 到你的另一个 table, unique()
d(只是为了证明当有超过每人 运行 个)。
可能有一种巧妙的方法可以结合两个 ddply
调用(或使用我不熟悉的 dplyr
pipe-y 语法),但我不知道它是什么。
我在 R 中有一个数据集,其中包含一系列人物、发生的事件以及它们发生的指定时间(以秒为单位,从 0 开始)。它看起来类似于:
event seconds person
1 0.0 Bob
2 15.0 Bob
3 28.5 Bob
4 32.0 Joe
5 38.0 Joe
6 41.0 Joe
7 42.5 Joe
8 55.0 Anne
9 58.0 Anne
我需要对每个名字进行过滤,这意味着为每个人排序的事件不会按顺序排列。
这看起来像一个例子(注意鲍勃如何不参与事件 4-40 等):
event seconds person
1 0.0 Bob
2 15.0 Bob
3 28.5 Bob
41 256.0 Bob
42 261.0 Bob
43 266.0 Bob
44 268.5 Bob
45 272.0 Bob
46 273.0 Bob
49 569.0 Bob
80 570.5 Bob
81 581.0 Bob
顺序相关的事件以1为增量分隔。我想找到相关事件的持续时间,例如事件1-3是一组,即28.5秒。事件 41-46 是另一组,持续 17 秒。这对于人员列中列出的所有姓名都是必需的。
我尝试使用 dplyr 过滤名称,然后使用 as.matrix 找出事件行之间的差异,并确定增量大于 1 的位置(表明它不再是当前事件序列的一部分) ).我还没有找到一种方法来根据此分配最大值和最小值来确定相关事件的持续时间。虽然解决方案不需要涉及此步骤,但这是我能想到的最接近的步骤。
最终目标是绘制每个人的非连续持续时间,以便直观地表示每个人对整个数据集的事件参与情况。
提前谢谢你。
使用这个:
DF <- read.table(text = "event seconds person
1 0.0 Bob
2 15.0 Bob
3 28.5 Bob
41 256.0 Bob
42 261.0 Bob
43 266.0 Bob
44 268.5 Bob
45 272.0 Bob
46 273.0 Bob
49 569.0 Bob
80 570.5 Bob
81 581.0 Bob", header = TRUE)
DF$personEvent <- cumsum(c(1L, diff(DF$event)) != 1L)
# event seconds person personEvent
#1 1 0.0 Bob 0
#2 2 15.0 Bob 0
#3 3 28.5 Bob 0
#4 41 256.0 Bob 1
#5 42 261.0 Bob 1
#6 43 266.0 Bob 1
#7 44 268.5 Bob 1
#8 45 272.0 Bob 1
#9 46 273.0 Bob 1
#10 49 569.0 Bob 2
#11 80 570.5 Bob 3
#12 81 581.0 Bob 3
既然我不是大烟斗的追随者,剩下的就交给你了。
假设首先我们只有 Bob 的数据框行,称为 bob
。
我们假设 bob
已经由 event
订购,递增。
按照您提到的相同思路(查看 diff(event) > 1
),您还可以使用 cumsum
将每个事件分组到它所属的 'run' 个事件中:
library(plyr)
bob2 <- mutate(bob, start = c(1, diff(bob$event) > 1), run=cumsum(start))
event seconds person start run
1 1 0.0 Bob 1 1
2 2 15.0 Bob 0 1
3 3 28.5 Bob 0 1
4 41 256.0 Bob 1 2
5 42 261.0 Bob 0 2
6 43 266.0 Bob 0 2
7 44 268.5 Bob 0 2
8 45 272.0 Bob 0 2
9 46 273.0 Bob 0 2
10 49 569.0 Bob 1 3
11 80 570.5 Bob 1 4
12 81 581.0 Bob 0 4
start
表示这是否启动了 运行 个连续事件,run
是我们所处的事件集。
那么你就可以找到持续时间:
ddply(bob2, .(run), summarize, length=diff(range(seconds)))
run length
1 1 28.5
2 2 17.0
3 3 0.0
4 4 10.5
现在假设你有原始数据框,每个人都混合在一起,我们可以再次使用 ddply
将其按人拆分:
tmp <- ddply(df, .(person), transform, run=cumsum(c(1, diff(event) != 1)))
ddply(tmp, .(person, run), summarize, length=diff(range(seconds)), start_event=first(event), end_event=last(event))
person run length start_event end_event
1 Anne 1 3.0 8 9
2 Bob 1 28.5 1 3
3 Bob 2 17.0 41 46
4 Bob 3 0.0 49 49
5 Bob 4 10.5 80 81
6 Joe 1 10.5 4 7
注意:我的 df
是你的 bob table rbind-ed 到你的另一个 table, unique()
d(只是为了证明当有超过每人 运行 个)。
可能有一种巧妙的方法可以结合两个 ddply
调用(或使用我不熟悉的 dplyr
pipe-y 语法),但我不知道它是什么。