[英]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.