Одна dplyr
возможность достичь этого может быть:
df %>%
mutate(episode = temperature > lag(temperature, default = first(temperature))) %>%
group_by(rleid = with(rle(episode), rep(seq_along(lengths), lengths))) %>%
mutate(episode = (n() >= 4) * episode) %>%
ungroup() %>%
select(-rleid) %>%
left_join(df %>%
mutate(episode = temperature < lag(temperature, default = first(temperature))) %>%
group_by(rleid = with(rle(episode), rep(seq_along(lengths), lengths))) %>%
mutate(episode = (n() >= 4) * episode) %>%
ungroup() %>%
select(-rleid), by = c("Patient" = "Patient",
"Minute" = "Minute",
"temperature" = "temperature")) %>%
mutate(episode = pmax(episode.x, episode.y)) %>%
select(-episode.x, -episode.y)
Patient Minute temperature episode
<int> <dbl> <dbl> <int>
1 1 0 35.6 0
2 1 1 35.6 0
3 1 2 35.7 1
4 1 3 35.7 1
5 1 4 35.7 1
6 1 5 35.7 1
7 1 6 35.7 0
8 1 7 35.7 0
9 1 8 35.7 0
10 1 9 35.7 0
11 1 10 35.7 0
12 1 11 35.7 0
Обратите внимание, что я уменьшил количество дней с 15 до 4 (вы можете изменить его, изменив число в n() >= 4
)поскольку ваши данные не содержат достаточного количества строк для иллюстрации за эти дни.
И то, что они делают, сначала сравнивает, есть ли строка выше / ниже (она делает это отдельно для двух условий)значение «температура», чем предыдущийВо-вторых, вокруг этого сравнения создается идентификатор группы типов длин серий.В-третьих, если условие выполняется для n
строк (в моем коде это 4), оно присваивает 1 переменной, называемой «эпизод».Наконец, он объединяет результаты сравнений с первого шага.
Или, если вы также хотите различить эпизоды:
df %>%
mutate(episode = temperature > lag(temperature, default = first(temperature))) %>%
group_by(rleid = with(rle(episode), rep(seq_along(lengths), lengths))) %>%
mutate(episode = (n() >= 2) * episode) %>%
ungroup() %>%
select(-rleid) %>%
left_join(df %>%
mutate(episode = temperature < lag(temperature, default = first(temperature))) %>%
group_by(rleid = with(rle(episode), rep(seq_along(lengths), lengths))) %>%
mutate(episode = ((n() >= 2) * episode + 1) * episode) %>%
ungroup() %>%
select(-rleid), by = c("Patient" = "Patient",
"Minute" = "Minute",
"temperature" = "temperature")) %>%
mutate(episode = pmax(episode.x, episode.y)) %>%
select(-episode.x, -episode.y)
Patient Minute temperature episode
<int> <dbl> <dbl> <dbl>
1 1 0 35.6 0
2 1 1 35.6 0
3 1 2 35.7 1
4 1 3 35.7 1
5 1 4 35.7 1
6 1 5 35.7 1
7 1 6 35.7 2
8 1 7 35.7 2
9 1 8 35.7 2
10 1 9 35.7 1
11 1 10 35.7 1
12 1 11 35.7 1
Здесь, используя 2 окна, «эпизод» ==1 означает увеличение, «эпизод» == 2 уменьшение.
И я полагаю, что вы хотели бы сгруппировать по «Пациент», так что вы можете сделать:
df %>%
group_by(Patient) %>%
mutate(episode = temperature > lag(temperature, default = first(temperature))) %>%
group_by(Patient, rleid = with(rle(episode), rep(seq_along(lengths), lengths))) %>%
mutate(episode = (n() >= 2) * episode) %>%
ungroup() %>%
select(-rleid) %>%
left_join(df %>%
group_by(Patient) %>%
mutate(episode = temperature < lag(temperature, default = first(temperature))) %>%
group_by(Patient, rleid = with(rle(episode), rep(seq_along(lengths), lengths))) %>%
mutate(episode = ((n() >= 2) * episode + 1) * episode) %>%
ungroup() %>%
select(-rleid), by = c("Patient" = "Patient",
"Minute" = "Minute",
"temperature" = "temperature")) %>%
mutate(episode = pmax(episode.x, episode.y)) %>%
select(-episode.x, -episode.y)