簡體   English   中英

根據第一個實例刪除行以滿足條件

[英]Remove rows based on first instance to meet a condition

在以下數據集中,我想刪除從第一個實例開始的所有行,按Time排序並按ID分組,即Var為 TRUE。 換句話說,我想通過在第一個 TRUE 之前為 FALSE 的行對每個ID的所有行進行子集化,按Time排序。

ID <- c('A','B','C','A','B','C','A','B','C','A','B','C')
Time <- c(3,3,3,6,6,6,9,9,9,12,12,12)
Var <- c(F,F,F,T,T,F,T,T,F,T,F,T)
data = data.frame(ID, Time, Var)

data
   ID Time   Var
1   A    3 FALSE
2   B    3 FALSE
3   C    3 FALSE
4   A    6  TRUE
5   B    6  TRUE
6   C    6 FALSE
7   A    9  TRUE
8   B    9  TRUE
9   C    9 FALSE
10  A   12  TRUE
11  B   12 FALSE
12  C   12  TRUE

此數據框的預期結果應該是:

 ID Time   Var
  A    3 FALSE
  B    3 FALSE
  C    3 FALSE
  C    6 FALSE
  C    9 FALSE

請注意,該解決方案不僅應刪除Var == TRUE 的行,還應刪除Var == FALSE 的行,但這會跟隨(在Time )另一個Var == TRUE 對於該ID實例。

我嘗試了很多不同的東西,但似乎無法弄清楚這一點。 非常感謝任何幫助!

以下是使用group_bycumsum使用dplyr執行此dplyr方法。

基本原理是 Var 是一個邏輯向量,其中 FALSE 等於 0,TRUE 等於cumsum將保持為 0,直到它達到第一個 TRUE。

library(dplyr)
data%>%
  group_by(ID)%>%
  filter(cumsum(Var)<1)

      ID  Time   Var
  <fctr> <dbl> <lgl>
1      A     3 FALSE
2      B     3 FALSE
3      C     3 FALSE
4      C     6 FALSE
5      C     9 FALSE

這是data.table的等效代碼:

library(data.table)
data[data[, .I[cumsum(Var) <1], by = ID]$V1]
   ID Time   Var
1:  A    3 FALSE
2:  B    3 FALSE
3:  C    3 FALSE
4:  C    6 FALSE
5:  C    9 FALSE

這個data.table解決方案應該可以工作。

library(data.table)
> setDT(data)[, .SD[1:(which.max(Var)-1)], by=ID]
   ID Time   Var
1:  A    3 FALSE
2:  B    3 FALSE
3:  C    3 FALSE
4:  C    6 FALSE
5:  C    9 FALSE

鑒於您希望所有值最多為第一個TRUE 值, which.max是要走的路。

你也可以用cumall動詞來做到這一點:

library(dplyr)

data %>% 
  dplyr::group_by(ID) %>% 
  dplyr::filter(dplyr::cumall(!Var))

  ID     Time Var  
  <chr> <dbl> <lgl>
1 A         3 FALSE
2 B         3 FALSE
3 C         3 FALSE
4 C         6 FALSE
5 C         9 FALSE

cumall(!x): 直到第一個 TRUE 的所有情況

暫無
暫無

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

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