2016-10-25 5 views
-3

Ich habe einige Daten mit IDs, Datumsangaben und ganzzahligen Werten für assoziierte ID und Startdatum Kombinationen, es gibt mehrere Daten pro ID.Überlappungen in Datentabelle finden

Ich mag eine Spalte erstellen angibt:

1) mich erzählen, wenn eine ID eine Summe hat> = 14 aus den ganzen Zahlen, oder eine Anzahl von 4 separaten ganzen Zahlen in einem Zeitraum von 12 Monaten.

Es gibt eine ähnliche Frage hier, aber die Kategorien von mir sind ein bisschen komplizierter: Create new column based on condition that exists within a rolling date

Jede Hilfe sehr zu schätzen! Hier

ist ein dput einiger Daten:

structure(list(ID = c("90939293", "90963328", "90092983", 
"90032926", "90944838", "90092983", "90062392", "90224939", "90202398", 
"90926203", "90936043", "90329263", "90944838", "90232033", "90980903", 
"90924463", "90299292", "90933383", "90209349", "90092983", "90022988", 
"90022293", "90933383", "90092983", "90299240", "90963033", "90004923", 
"90292998", "90986096", "90980903", "90336692", "90933383", "90022988", 
"90069992", "90062392", "90209248", "90924463", "90092983", "90933383", 
"90022293", "90062392", "90004923", "90233269", "90329263", "90229202", 
"90309943", "90299292", "90036820", "90329263", "90232033", "90329263", 
"90336692", "90963033", "90224939", "90924463", "90069992", "90092983", 
"90934923", "90926203", "90222333", "90092983", "90299292", "90202398", 
"90004923", "90233269", "90926203", "90222333", "90224939", "90232033", 
"90933383", "90022293", "90022988", "90934923", "90069992", "90329263", 
"90209349", "90022293", "90309943", "90299240", "90022293", "90336692", 
"90020334", "90933383", "90290384", "90224939", "90980903", "90299240", 
"90299292", "90202398", "90022346"), Date = structure(c(15972, 
16009, 16010, 16010, 16007, 16010, 16006, 16010, 16007, 16008, 
15997, 16007, 16007, 16002, 16008, 16006, 16006, 16006, 16009, 
16010, 16006, 16006, 16006, 16010, 15995, 16008, 16008, 16010, 
16009, 16008, 16010, 16006, 16006, 16009, 16006, 16006, 16006, 
16010, 16006, 16006, 16006, 16008, 16009, 16007, 16010, 16007, 
16006, 16009, 16007, 16002, 16007, 16010, 16008, 16010, 16006, 
16009, 16010, 15936, 16008, 16008, 16010, 16006, 16007, 16008, 
16009, 16008, 16008, 16010, 16002, 16006, 16006, 16006, 15936, 
16009, 16007, 16009, 16006, 16007, 15995, 16006, 16010, 16006, 
16006, 16010, 16010, 16008, 15995, 16006, 16007, 16008), class = "Date"), 
    Integer = c(39, 2, 1, 1, 4, 1, 5, 1, 4, 3, 14, 4, 4, 9, 
    3, 5, 5, 5, 2, 1, 5, 5, 5, 1, 16, 3, 3, 1, 2, 3, 1, 5, 5, 
    2, 5, 5, 5, 1, 5, 5, 5, 3, 2, 4, 1, 4, 5, 2, 4, 9, 4, 1, 
    3, 1, 5, 2, 1, 75, 3, 3, 1, 5, 4, 3, 2, 3, 3, 1, 9, 5, 5, 
    5, 75, 2, 4, 2, 5, 4, 16, 5, 1, 5, 5, 1, 1, 3, 16, 5, 4, 
    3)), .Names = c("ID", "Date", "Integer" 
), row.names = c("200086", "200066", "200050", "200064", "200078", 
"200050.1", "200069", "200082", "200083", "200053", "200056", 
"200055", "200078.1", "200079", "200051", "200089", "200052", 
"200057", "200061", "200050.2", "200060", "200080", "200057.1", 
"200050.3", "200068", "200071", "200070", "200059", "200062", 
"200051.1", "200067", "200057.2", "200060.1", "200072", "200069.1", 
"200073", "200089.1", "200050.4", "200057.3", "200080.1", "200069.2", 
"200070.1", "200081", "200054", "200063", "200075", "200052.1", 
"200074", "200054.1", "200079.1", "200055.1", "200067.1", "200071.1", 
"200082.1", "200089.2", "200072.1", "200050.5", "200084", "200053.1", 
"200088", "200050.6", "200052.2", "200083.1", "200070.2", "200081.1", 
"200053.2", "200088.1", "200082.2", "200079.2", "200057.4", "200080.2", 
"200060.2", "200084.1", "200072.2", "200055.2", "200061.1", "200080.3", 
"200075.1", "200068.1", "200080.4", "200067.2", "200065", "200057.5", 
"200090", "200082.3", "200051.2", "200068.2", "200052.3", "200083.2", 
"200076"), class = "data.frame") 
+5

"gibt es mehrere Termine pro ID" - 'any (dupliziert (df $ X1))' nicht einverstanden mit Ihnen für Ihre Beispieldaten. Ihre IDs (erste Spalte, ich nehme an, in Ihrem Beispiel heißen sie nur "X1") sind eindeutig. Oder meinst du mehrere IDs für einige Daten? Wie auch immer, machen Sie ein ** kleines ** Beispiel statt 100 Zeilen. – Spacedman

+0

Das ist nicht klar: "Ich werde informiert, wenn eine ID in einem Zeitraum von 12 Monaten eine Summe von 14 ganzen Zahlen oder 4 separaten ganzen Zahlen hat". Was bedeutet "eine Summe von 14 ganzen Zahlen"? 1 + 2 + 3 + 4 + 1 + 2 + 3 + 4 + 1 + 2 + 3 + 4 + 7 + 99 ist eine Summe von 14 ganzen Zahlen. Du meinst das nicht, oder? – Spacedman

+0

Ich denke, dass Sie wahrscheinlich zu viele Fragen stellen, und SO entmutigt teilweise Antworten, so dass, wenn sich eine Person nicht alle Ihre Probleme durcharbeitet, Sie keine Antworten erhalten werden. Ich schlage vor, Sie löschen diesen Beitrag und erstellen mehrere - die erste wird sein, wie zu finden, welche IDs Summen ihrer 'Integer'-Spalte Werte gleich 14 haben. – Spacedman

Antwort

1

mit Ihrem dput als 'x':

library(data.table) 

setDT(x, key = "Date") 

# test 1 
x[, `:=` (
    test1 = sum(Integer) >= 14 
), by = ID] 

# test2 
y = x[, .(
    count12 = uniqueN(Integer) 
), by = .(start = Date, end = Date - 365)] 

# combine 
z = merge(x, y, by.x = "Date", by.y = "start") 
z[, end := NULL] 
z[, flag := test1 | count12 == 4] 
1

Hier ist ein Stich an, was Sie fordern. Jetzt ist das Auffinden von IDs mit der Summe ihrer Ganzzahl größer als 14 so einfach wie das Gruppieren nach ID und Prüfen, ob die Summe der Integer-Spalte für jede ID> = 14 ist, oder in dplyr: df %>% group_by(ID) %>% mutate(conditional = sum(Integer) >= 14). Eine ID mit (mindestens?) 4 in einem Zeitraum von 12 Monaten zu finden, ist natürlich schwieriger. Meine Lösung folgt this Antwort bei der Berechnung der Fensteranzahl.

Es gibt nur eine Einschränkung: Da roll_sum funktioniert durch Rollen über die Anzahl der Zeilen, die Lösung, die ich benutze verlässt sich darauf, dass nur eine Zeile pro Tag pro ID. In Ihrem Beispieldatenfeld gibt es tatsächlich mehrere Einträge für das gleiche ID-Datum, aber es scheint sich um Duplikate zu handeln, daher habe ich sie entfernt. Falls dies nicht der Fall ist und die doppelten Werte für die Bedingung sum(Integer) >= 14 berechnet werden müssen, können sie vorher entfernt werden (z. B. df %>% group_by(ID, Date) %>% summarize(Integer = sum(Integer))), so dass pro ID pro Datum nur ein Eintrag vorhanden ist.

library(dplyr) 
library(tidyr) 
library(RcppRoll) 

df_tmp <- df 
df <- df_tmp %>% 
    group_by(ID, Date) %>% 
    filter(n() == 1) %>% # this line removes duplicate columns 
    ungroup() %>% 
    complete(ID, 
      Date=seq(from=min(Date)-365,to=max(Date), by=1), 
      fill=list(Integer=0)) %>% # we use complete to add in a row for all IDs for every single date since a year before the first obs. 
    arrange(ID, Date) %>% 
    group_by(ID) %>% 
    mutate(roll_count = roll_sum(x = Integer != 0, n = 365, fill=0, align="right"), # this calculates the rolling sum using n = 365 as a stand-in for 12 months 
     conditional = sum(Integer) >= 14 || roll_count >= 4) %>% 
    ungroup() %>% 
    right_join(df, by = c("ID","Date", "Integer")) # right_join with the original data to remove dummy dates 

Hoffe, das hilft!

Verwandte Themen