在以下数据集中,我想删除从第一个实例开始的所有行,按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
)另一个实例中删除对于Var
,ID
== TRUE。
我尝试过很多不同的东西,但似乎无法解决这个问题。非常感谢任何帮助!
答案 0 :(得分:2)
以下是dplyr
使用group_by
和cumsum
的方法。
基本原理是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 的所有情况