使用顺序数据在dplyr中标记条件事件

时间:2019-04-26 08:46:58

标签: r dplyr

在下面的示例中,事件开始定义为“值”的先前值大于等于90并且当前值小于90。事件结束表示当前值小于90而下一个值等于90以上。

sequential_index <- seq(1,10)
values <- c(91,90,89,89,90,90,89,88,90,91)
df <- data.frame(sequential_index, values)

上例中的df,观察值3-4发生第一个事件,观察值7-8发生第二个事件。我试图无济于事,在上面的数据框中添加一个“事件”列,看起来像这样:

       sequential_index values events
1                 1     91     NA
2                 2     90     NA
3                 3     89      1
4                 4     89      1
5                 5     90     NA
6                 6     90     NA
7                 7     89      2
8                 8     88      2
9                 9     90     NA
10               10     91     NA

我的数据集非常大,我正在尝试避免for循环。
提前致谢, -jt

2 个答案:

答案 0 :(得分:3)

我有使用dplyr的解决方案。

library(dplyr)

df %>%
# Define the start of events (putting 1 at the start of events)
mutate(events = case_when(lag(values)>=90 & values<90 ~ 1, TRUE ~ 0)) %>%
# Extend the events using cumsum()
mutate(events = case_when(values<90 ~ cumsum(events)))

输出:

   sequential_index values events
1                 1     91     NA
2                 2     90     NA
3                 3     89      1
4                 4     89      1
5                 5     90     NA
6                 6     90     NA
7                 7     89      2
8                 8     88      2
9                 9     90     NA
10               10     91     NA

答案 1 :(得分:2)

带有base R的一个选项是rle

df$events <- inverse.rle(within.list(rle(df$values < 90), 
        values[values] <- seq_along(values[values])
         ))
df$events[df$events == 0] <- NA
df$events
#[1] NA NA  1  1 NA NA  2  2 NA NA

或者以紧凑的方式与data.table

library(data.table)
setDT(df)[, events := as.integer(factor(rleid(events < 90)[events < 90]))]