簡體   English   中英

在 R 中選擇滿足特定條件的特定行和以下行

[英]Selecting specific rows and following ones which meet certain criteria in 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

我需要 select 有警告 [1] 的那些,我還需要 select 在壓力值高於 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 中有沒有辦法做到這一點?

感謝您的任何建議。

嘗試這個。 基本思想是首先按“警告組”對 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

代表 package (v0.3.0) 於 2020 年 4 月 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)

data.table解決方案

邏輯與@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

代表 package (v0.3.0) 於 2020 年 4 月 17 日創建

這是一個基本的 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM