2016-11-04 2 views
0

Dies ist meine Daten, möchte ich für eine ID nach einem Ereignis für ID-Nummer 1,Wie entferne ich die Daten nach einem Ereignis?

ID Event time 
1  0  1 
1  1  2 
2  0  3 
1  0  4 
2  0  5 

Da alle Daten entfernen, wurde die Veranstaltung größer als 0, würde Ich mag die ganze nächste Daten löschen von ID 1. So, ich entferne Reihe Nr. 4 und meine ideale Ausgabe ist

Wie kann ich das tun?

dput(df) 
structure(list(ID = c(1L, 1L, 2L, 1L, 2L), Event = c(0L, 1L, 
0L, 0L, 0L), time = 1:5), .Names = c("ID", "Event", "time"), class = "data.frame", row.names = c(NA, 
-5L)) 
+0

habe ich versucht, etwas sehr kompliziert und erstellt Schlepptau Satz von Datensätzen für diejenigen, die Veranstaltung und für diejenigen hatte, die noch nicht haben, zugewiesen ich eine Zeitreihe für beide sie und haben 'output <-filter (mydata, is.na (Time.y) | last (Time.y)> last (Time.x))' und schließlich gab es mir meine gewünschte Ausgabe nicht. Ich dachte, es gibt eine einfache Möglichkeit, dass ich vermisse – MFR

+1

Ich gehe davon aus, dass das "dplyr :: filter", nicht "stats :: filter" ist. Mit dplyr, 'df%>% group_by (ID)%>% Filter (Zeit <= min (was (Ereignis == 1))) funktioniert. – alistaire

+0

Danke @alistaire. Du bist toll! – MFR

Antwort

4

Mit dplyr können Sie filter für time Werte kleiner als das Minimum ein, wo Event 1 ist, gruppiert nach ID:

library(dplyr) 

df %>% group_by(ID) %>% filter(time <= min(time[Event == 1])) 

## Source: local data frame [4 x 3] 
## Groups: ID [2] 
## 
##  ID Event time 
## <int> <int> <int> 
## 1  1  0  1 
## 2  1  1  2 
## 3  2  0  3 
## 4  2  0  5 

Statt time zu verwenden, Sie row_number oder seq mit which verwenden könnte . In Basis R, könnten Sie ave verwenden, um die Gruppierung zu handhaben, aber es kann nur einen Eingangsvektor verarbeiten, so dass ein seq Ansatz ist einfacher als die Arbeit mit time:

df[as.logical(ave(df$Event, df$ID, FUN = function(x) { 
    seq_along(x) <= min(which(x == 1)) 
})), ] 

## ID Event time 
## 1 1  0 1 
## 2 1  1 2 
## 3 2  0 3 
## 5 2  0 5 

Beiden Ansätzen auf der Tatsache beruhen, dass min(integer(0)) kehrt Inf Wenn es keine 1 Werte für einen ID gibt, aber fügen Sie eine if Bedingung hinzu, um die Situation explizit zu berücksichtigen, wenn Sie möchten.

+0

Ich dachte, es muss etwas Einfaches hier sein, aber ich könnte es nicht wirklich besser. Mein bester Versuch war 'df [! Ave (df $ Ereignis, df $ ID, FUN = Funktion (x) rev (cumsum (rev (x))) == 0 & jedes (x)),]' – thelatemail

1

Hier ist eine Option match mit mit data.table

library(data.table) 
setDT(df)[, .SD[seq_len(match(1, Event, nomatch = .N))], ID] 
# ID Event time 
#1: 1  0 1 
#2: 1  1 2 
#3: 2  0 3 
#4: 2  0 5 
Verwandte Themen