2016-09-30 71 views
1

我有一個包含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 

回答

3

我們可以試試dplyr。在'ID'分組後,檢查'event'中的元素all是否爲(all(event == 0))或(|)行序列小於或等於'event'的第一個最大元素(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,並檢查它是否是小於2的filter通話。

df %>% 
    group_by(ID) %>% 
    filter(cumsum(cumsum(event == 1))<2) 

或者用data.table,轉換 'data.frame' 到 'data.table'(setDT(df))中,由 'ID' ifall的 '事件' 的元素是0分組,子集中的數據.table(.SD)或else子集Data.table中的行包含'event'中的第一個到第一個最大元素。

library(data.table) 
setDT(df)[, if(all(event==0)) .SD else .SD[seq(which.max(event))], by = ID] 
+1

感謝您的解釋,我試圖瞭解所有(事件== 0)部分。 –

相關問題