Выбор определенных c строк и следующих, которые соответствуют определенным критериям в R - PullRequest
2 голосов
/ 16 апреля 2020

У меня есть большой набор данных [df], например, такой:

id   device   date                pressure    warning
1    B3       2020-04-15 08:00    112         0
2    B3       2020-04-15 09:00    67          1
3    B3       2020-04-15 10:00    13          0
4    B3       2020-04-15 11:00    0           0
5    B3       2020-04-15 12:00    12          0
6    B3       2020-04-15 13:00    28          0
7    B3       2020-04-16 09:00    120         0
8    B3       2020-04-16 10:00    80          1
9    B3       2020-04-16 11:00    0           0
10   B3       2020-04-16 12:00    19          0
11   B3       2020-04-16 13:00    30          0

Мне нужно выбрать те, которые имеют предупреждение [1], и мне также нужно выбрать первую строку после предупреждения с значение давления выше 20 [давление> = 20].

Ожидаемый результат будет выглядеть следующим образом:

id   device   date                pressure    warning
2    B3       2020-04-15 09:00    67          1
6    B3       2020-04-15 13:00    28          0
8    B3       2020-04-16 10:00    80          1
11   B3       2020-04-16 13:00    30          0

Есть ли способ сделать это в R или SQL?

Спасибо за любые предложения.

Ответы [ 3 ]

2 голосов
/ 16 апреля 2020

Попробуй это. Основная идея c заключается в том, чтобы сначала сгруппировать df по «группам предупреждений». Затем внутри групп мы можем выбрать первые obs, которые вызвали предупреждение, а также первые следующие obs, где давление выше 20. Спасибо @Ben за значительное упрощение моего исходного кода:

Edit:

library(dplyr)

df %>% 
  group_by(grp = cumsum(warning)) %>% 
  filter(any(warning == 1), warning == 1 | pressure >= 20) %>% 
  slice(1:2) %>% 
  # Drop helpers
  select(-grp)
#> # A tibble: 4 x 6
#> # Groups:   warning1 [2]
#>   warning1 id    device     date  pressure warning
#>      <int> <chr> <chr>      <chr>    <int>   <int>
#> 1        1 B3    2020-04-15 09:00       67       1
#> 2        1 B3    2020-04-15 13:00       28       0
#> 3        2 B3    2020-04-16 10:00       80       1
#> 4        2 B3    2020-04-16 13:00       30       0

Создано в 2020-04-16 пакетом представ (v0.3.0)

Оригинальный код:

df %>% 
  # Warnings group
  mutate(warning1 = cumsum(warning)) %>%
  # Group by warnings group
  group_by(warning1) %>%
  # Pressure counter by warnings group
  mutate(pressure1 = cumsum(pressure >= 20 & warning == 0)) %>% 
  # Filter: 
  # 1. Keep obs where warning is initiated (warning == 1)
  # 2. Keep first following obs with pressure >= 20 
  filter(warning == 1 | (warning1 > 0 & pressure >= 20 & warning == 0 & pressure1 == 1)) %>% 
  # Drop helpers
  select(-warning1, -pressure1)
1 голос
/ 16 апреля 2020

Вот базовое решение R

ind1 <- which(df$warning==1)
ind2 <- which(df$pressure >= 20)
dfout <- df[sort(c(ind1,sapply(ind1, function(x) min(ind2[ind2 > x])))),]

такое, что

> dfout
   id     device  date pressure warning
2  B3 2020-04-15 09:00       67       1
6  B3 2020-04-15 13:00       28       0
8  B3 2020-04-16 10:00       80       1
11 B3 2020-04-16 13:00       30       0
1 голос
/ 16 апреля 2020

A data.table решение

Лог c совпадает с ответом @ stefan.

library(data.table)

dt <- fread('id device  date                pressure    warning
1   B3      2020/4/15 8:00  112 0
2   B3      2020/4/15 9:00  67  1
3   B3      2020/4/15 10:00 13  0
4   B3      2020/4/15 11:00 0   0
5   B3      2020/4/15 12:00 12  0
6   B3      2020/4/15 13:00 28  0
7   B3      2020/4/16 9:00  120 0
8   B3      2020/4/16 10:00 80  1
9   B3      2020/4/16 11:00 0   0
10  B3      2020/4/16 12:00 19  0
11  B3      2020/4/16 13:00 30  0
')


dt[,grp:=cumsum(warning)]

dt[warning==1|pressure>20&grp>0,head(.SD,2),by=.(grp)]
#>    grp id device            date pressure warning
#> 1:   1  2     B3  2020/4/15 9:00       67       1
#> 2:   1  6     B3 2020/4/15 13:00       28       0
#> 3:   2  8     B3 2020/4/16 10:00       80       1
#> 4:   2 11     B3 2020/4/16 13:00       30       0

Создано в 2020-04-17 Представить пакет (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...