问题描述
我得到了纵向数据集,我想在感兴趣的事件发生后放弃观察。这意味着我想在指示感兴趣的 event
发生的虚拟变量(即 event == 1
)之后删除所有观察结果。数据看起来像这样:
id <- c(1,1,2,3,4,5,5)
time <- c(1,3)
event <- c(0,0)
df <- cbind(id,time,event)
id time event
[1,] 1 1 0
[2,] 1 2 1
[3,] 1 3 0
[4,] 2 1 1
[5,] 2 2 0
[6,] 2 3 0
[7,] 3 1 0
[8,] 3 2 0
[9,] 3 3 0
[10,] 4 1 0
[11,] 4 2 1
[12,] 4 3 0
[13,] 5 1 1
[14,] 5 2 0
[15,] 5 3 0
我想在事件发生后放弃所有后续观察(为了清楚起见:event == 1
),以便 id
。导致数据集如下所示:
id time event
[1,] 1 1 0
[2,] 1 2 1
[3,] 2 1 1
[4,] 3 1 0
[5,] 3 2 0
[6,] 3 3 0
[7,] 4 1 0
[8,] 4 2 1
[9,] 5 1 1
我最大的问题是如何在时间变量上调整后续观察的删除。
提前致谢! :D
解决方法
如果数据构造为data.frame
,那么我们可以在dplyr
中使用group by操作,即按'id'分组,获取事件中第一次出现1的位置索引,如果有任何并获取序列,否则返回行序列
library(dplyr)
df %>%
arrange(id,time) %>%
group_by(id) %>%
slice(if(1 %in% event) seq(match(1,event)) else row_number()) %>%
ungroup
-输出
# A tibble: 9 x 3
# id time event
# <dbl> <dbl> <dbl>
#1 1 1 0
#2 1 2 1
#3 2 1 1
#4 3 1 0
#5 3 2 0
#6 3 3 0
#7 4 1 0
#8 4 2 1
#9 5 1 1
如果我们将 if/else
指定为行数 (nomatch
),也可以在没有 n()
的情况下使其更短
df %>%
arrange(id,time) %>%
group_by(id) %>%
slice(seq(match(1,event,nomatch = n())))
数据
df <- data.frame(id,time,event)
,
seq_len()
的解决方案
library(dplyr)
df %>%
arrange(id,time) %>%
group_by(id) %>%
slice(seq_len(min(which(event == 1),n())))
数据
id <- c(1,1,2,3,4,5,5)
time <- c(1,3)
event <- c(0,0)
df <- data.frame(id,event)
# output:
# Groups: id [5]
id time event
<dbl> <dbl> <dbl>
1 1 1 0
2 1 2 1
3 2 1 1
4 3 1 0
5 3 2 0
6 3 3 0
7 4 1 0
8 4 2 1
9 5 1 1