R 有条件地从数据帧中删除行(多个条件)

R 有条件地从数据帧中删除行(多个条件),r,conditional,dataframe,R,Conditional,Dataframe,我已经搜索了这么多,尽管有很多QA关于有条件地删除行,但没有一个QA适合我的问题 我有一个data.frame包含变量x,y等的纵向测量值,在多个受试者的不同时间点time,id。一些受试者在某个时间经历事件ev(表示为1,否则0)。我想将初始data.frame缩减为: 1) 所有包含未经历事件的主题的行(好的,这很容易),但也包括 2) 对于经历过事件的受试者,事件发生前的所有行(即时间小于该个体事件发生时间的所有行) 所以, testdf<-data.frame(id=c(rep

我已经搜索了这么多,尽管有很多QA关于有条件地删除行,但没有一个QA适合我的问题

我有一个
data.frame
包含变量
x
y
等的纵向测量值,在多个受试者的不同时间点
time
id
。一些受试者在某个
时间经历事件
ev
(表示为
1
,否则
0
)。我想将初始
data.frame
缩减为:

  • 1) 所有包含未经历事件的主题的行(好的,这很容易),但也包括
  • 2) 对于经历过事件的受试者,事件发生前的所有行(即时间小于该个体事件发生时间的所有行)
所以,

testdf<-data.frame(id=c(rep("A",4),rep("B",4),rep("C",4) ),
                   x=c(NA, NA, 1,2, 3, NA, NA, 1, 2, NA,NA, 5), 
                   y=rev(c(NA, NA, 1,2, 3, NA, NA, 1, 2, NA,NA, 5)),
                   time=c(1,2,3,4,0.1,0.5,10,20,3,2,1,0.5),
                   ev=c(0,0,0,0,0,1,0,0,0,0,0,1))

这个使用
data.table
的解决方案似乎适用于
testdf
。想法是使用
cumsum
跟踪第一个事件开始后的位置

require(data.table)
dt <- data.table(testdf, key=c("id"))
dt.out <- dt[, .SD[cumsum(ev) == 0], by=id]
> dt.out

#    id  x  y time ev
# 1:  A NA  5  1.0  0
# 2:  A NA NA  2.0  0
# 3:  A  1 NA  3.0  0
# 4:  A  2  2  4.0  0
# 5:  B  3  1  0.1  0
# 6:  C  2  2  3.0  0
# 7:  C NA  1  2.0  0
# 8:  C NA NA  1.0  0
require(data.table)
dt以下是一个示例:

> ddply(testdf, .(id), function(z) z[cumsum(z$ev) == 0, ])
  id  x  y time ev
1  A NA  5  1.0  0
2  A NA NA  2.0  0
3  A  1 NA  3.0  0
4  A  2  2  4.0  0
5  B  3  1  0.1  0
6  C  2  2  3.0  0
7  C NA  1  2.0  0
8  C NA NA  1.0  0
base中的解决方案:

> do.call(rbind, by(testdf, testdf$id, function(x) x[cumsum(x$ev) == 0,]))
     id  x  y time ev
A.1   A NA  5  1.0  0
A.2   A NA NA  2.0  0
A.3   A  1 NA  3.0  0
A.4   A  2  2  4.0  0
B     B  3  1  0.1  0
C.9   C  2  2  3.0  0
C.10  C NA  1  2.0  0
C.11  C NA NA  1.0  0

下面是一个包含
子集
ave
的解决方案:

subset(testdf, !ave(ev, id, FUN = cumsum))

注意,如果条件2被写为“事件之前的所有行”,则条件2意味着条件1。或者,
testdf[with(testdf,ave(ev,id,FUN=cumsum))==0,]
subset(testdf, !ave(ev, id, FUN = cumsum))