首页 > 解决方案 > 选择特定行并遵循 R 中满足特定条件的行

问题描述

我有一个大型数据集 [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 中做到这一点?

感谢您的任何建议。

标签: rdataframe

解决方案


尝试这个。基本思想是首先按“警告组”对 df 进行分组。在这些组中,我们可以选择触发警告的第一个 obs 以及压力高于 20 的第一个以下 obs。感谢@Ben 大大简化了我的原始代码:

编辑:

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

reprex 包(v0.3.0)于 2020-04-16 创建

原始代码:

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)

推荐阅读