Маркировка условных событий в dplyr последовательными данными - PullRequest
5 голосов
/ 26 апреля 2019

В приведенном ниже примере начало события определяется как то, когда предыдущее значение «значений» равно 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.Я пытаюсь, но безрезультатно, добавить столбец «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

Мой набор данных довольно большой, и я пытаюсь избежать циклов.
Заранее спасибо, -jt

Ответы [ 2 ]

3 голосов
/ 26 апреля 2019

У меня есть это решение с использованием 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
2 голосов
/ 26 апреля 2019

Один вариант с 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]))]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...