根据第一个实例删除行以满足条件

时间:2017-06-15 20:24:05

标签: r

在以下数据集中,我想删除从第一个实例开始的所有行,按Time排序并按ID分组,Var为TRUE。换句话说,我希望将每个ID的所有行按FALSE排序,直到第一个为TRUE,按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)另一个实例中删除对于VarID == TRUE。

我尝试过很多不同的东西,但似乎无法解决这个问题。非常感谢任何帮助!

3 个答案:

答案 0 :(得分:2)

以下是dplyr使用group_bycumsum的方法。

基本原理是Var是一个逻辑向量,其中FALSE等于0且TRUE等于1. 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

答案 1 :(得分:0)

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就可以了。

答案 2 :(得分:0)

您也可以使用 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 的所有情况