我有一个包含ID,日期和事件的数据集。事件是二进制结果变量。每个ID最多只能有一个事件。该事件后可能有多个0。我想按组删除事件后出现的所有零。我在下面有一个使用dplyr的解决方案,但很想知道是否有更好的方法。指示某个事件在过去某个时间点发生过的好的方法是什么?
library(dplyr)
d <-as.Date("01-05-15", "%d-%m-%y")
#Starting dataset
df <- data.frame(ID= c(rep(234,4),rep(235,6), rep(237,5)),
date = as.Date(c((d-4):(d-1),(d-1):(d+4),(d+1):(d+5)),origin="1960-10-01"),
event = c(0,1,0,0,0,0,0,0,0,0,0,0,0,1,0))
#desired result
df[c(1:2,5:14),]
#How can Improve this?
df %>% group_by(ID) %>%
mutate(cumulative = lag(cumsum(event), default = 0)) %>%
filter(cumulative <1) %>%
select(-cumulative) %>% ungroup
我们可以尝试一下dplyr
。按“ ID”分组后,检查all
“事件”中的元素是否为0(all(event == 0)
)或(|
)行序列小于或等于“事件”(row_number() <= which.max(event)
)的第一个最大元素的索引,并使用该逻辑索引来filter
行。
library(dplyr)
df %>%
group_by(ID) %>%
filter(row_number() <= which.max(event)|all(event==0))
# ID date event
# <dbl> <date> <dbl>
#1 234 2015-04-27 0
#2 234 2015-04-28 1
#3 235 2015-04-30 0
#4 235 2015-05-01 0
#5 235 2015-05-02 0
#6 235 2015-05-03 0
#7 235 2015-05-04 0
#8 235 2015-05-05 0
#9 237 2015-05-02 0
#10 237 2015-05-03 0
#11 237 2015-05-04 0
#12 237 2015-05-05 1
或者更紧凑的选择event
是等于1并检查filter
调用中是否小于2的double累积总和。
df %>%
group_by(ID) %>%
filter(cumsum(cumsum(event == 1))<2)
或使用data.table
,将'data.frame'转换为'data.table'(setDT(df)
),按'ID'分组,将if
all
'event'的元素设置为0,对Data.table(.SD
)进行else
子集设置,或对Data.table进行子集设置,包括从“事件”中的第一个到第一个最大元素。
library(data.table)
setDT(df)[, if(all(event==0)) .SD else .SD[seq(which.max(event))], by = ID]
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句