2016-09-30 4 views
1

Ich habe einen Datensatz mit ID, Datum und Ereignis. Ereignis ist eine binäre Ergebnisvariable. Es kann immer nur maximal ein Ereignis pro ID geben. Auf das Ereignis können weitere Nullen folgen. Ich möchte alle Nullen entfernen, die nach dem Ereignis nach Gruppe angezeigt werden. Ich habe eine Lösung mit dplyr unten, bin aber interessiert zu wissen, ob es eine bessere Methode gibt. Was ist ein guter Hinweis darauf, dass ein Ereignis in der Vergangenheit stattgefunden hat?Entfernen von Zeilen aus gruppierten Daten nach einem Ereignis

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 

Antwort

3

Wir können mit dplyr versuchen. Überprüfen Sie nach der Gruppierung nach 'ID', ob all die Elemente in 'Ereignis' 0 (all(event == 0)) oder (|) Sequenz von Zeilen ist kleiner oder gleich dem Index des ersten maximalen Elements von 'Ereignis' (row_number() <= which.max(event)) und verwenden dieser logische Index zu filter die Zeilen.

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 

Oder etwas kompaktere Option ein Doppel kumulative Summe auf den event wäre, die gleich 1 ist und zu prüfen, ob es weniger als 2 in dem filter Anruf.

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

Oder data.table verwenden, wandeln die 'data.frame' auf 'data.table' (setDT(df)), gruppiert nach 'ID' ifall das Element der 'Ereignis' ist 0, Subset der Daten .table (.SD) oder else Unterteilen Sie die Data.table mit den Zeilen vom ersten bis zum ersten maximalen Element in 'event'.

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

Danke für die Erklärung Ich habe versucht, alles (event == 0) Teil zu verstehen. –

Verwandte Themen