Определение эпизодов в продольных данных - PullRequest
0 голосов
/ 22 мая 2019

У меня есть набор данных, в котором я хотел бы определить «эпизоды». Эпизод определяется, если есть повышение или понижение температуры в течение по крайней мере 15 минут. Есть ли способ структурировать это, не делая это вручную?

Это структура моих данных:

Patient  Minute temperature
1 0,00  35,65
1 1,00  35,65
1 2,00  35,66
1 3,00  35,67
1 4,00  35,70
1 5,00  35,72
1 6,00  35,71
1 7,00  35,68
1 8,00  35,66
1 9,00  35,67
1 10,00 35,69
1 11,00 35,72

Заранее спасибо.

1 Ответ

0 голосов
/ 22 мая 2019

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