2017-03-15 1 views
1

Ich habe 2 Datenrahmen wie dieseMerge 2 Datenrahmen mit Bedingungen auf Datetimes und bekommen die Zählungen für passfails

df1

ID <- c("ID001","ID001","ID002","ID003") 
Type <- c("A","A","B","A") 
Measurement <- c("Length","Breadth","Length","Length") 
When <- c("2016-09-09 06:00:13", "2016-09-19 09:13:10", "2016-10-13 11:45:14", "2016-10-29 11:56:00") 

df1 <- data.frame(ID,Type,Measurement,When) 

df2

ID <- c("ID001","ID001","ID001","ID001","ID001", 
      "ID002","ID002","ID002","ID002","ID002") 
    Type <- c("A","A","A","A","A", 
       "B","B","B","B","B") 
    Measurement <- c("Length","Length","Length","Length","Length", 
        "Length","Length","Length","Length","Length") 
    Datetime <- c("2016-09-09 01:00:13", "2016-09-09 04:00:13", "2016-09-09 09:00:13", "2016-09-09 21:00:13","2016-09-09 23:00:13", 
        "2016-10-13 10:45:14", "2016-10-13 11:15:14", "2016-10-13 11:48:14", "2016-10-13 11:55:14","2016-10-13 21:45:14") 
    PassFail <- c("Pass","Fail","Pass","Fail","Pass", 
        "Fail","Fail","Pass","Pass","Pass") 

    df2 <- data.frame(ID,Type,Measurement,Datetime,PassFail) 

ich versuche zu füge diese 2 Datenrahmen zusammen, um Zählungen von Durchgängen zu erhalten, und scheitere nur für Messungen für "Datetime" in df2 größer als "WANN" in df1.

Meine gewünschte Ausgabe ist

ID Type Measurement    When PassCount FailCount 
    ID001 A  Length 2016-09-09 06:00:13   2   1 
    ID002 B  Length 2016-10-13 11:45:14   3   0 

Ich versuchte sqldf mit diesen

library(sqldf) 
df3<-sqldf("SELECT L.*, r.Datetime, r.PASSFAIL 
      FROM df1 as L 
      LEFT JOIN df2 as r 
      ON L.ID=r.ID 
      AND L.Type=r.Type 
      AND L.Measurement=r.Measurement 
      WHERE r.Datetime > L.When 
      ORDER BY L.When") 

bekommen ich nicht erfolgreich bin ist an den Ausgang zu erhalten. Könnte mir jemand in die richtige Richtung zeigen? Ich möchte auch eine schnelle Merge-Lösung, da ich es auf einen größeren Datensatz anwenden möchte.

+0

Bitte Datum Zeitformate verwenden, keine Faktoren. – Frank

+0

dplyr hat Funktionen wie left_join, filter, group_by, fasse zusammen, das sollte es lösen –

Antwort

4

Mit data.table, ein nicht-equi kommen scheint zu funktionieren:

library(data.table) 
setDT(df1)[, When := as.POSIXct(When)] 
setDT(df2)[, Datetime := as.POSIXct(Datetime)] 

df2[df1, on=.(ID, Datetime > When), if (.N > 0L) as.list(table(PassFail)), by=.EACHI] 

#  ID   Datetime Fail Pass 
# 1: ID001 2016-09-09 06:00:13 1 2 
# 2: ID002 2016-10-13 11:45:14 0 3 

Wenn Sie eine Zeile für jede Zeile von df1 möchten, entfernen Sie die if Klausel.

Um die Zählungen als Spalten zu df1 hinzufügen:

df1[, levels(df2$PassFail) := 
    df2[df1, on=.(ID, Datetime > When), as.list(table(PassFail)), by=.EACHI][, !c("ID","Datetime")] 
] 
+2

Wunderbare Lösung. Es hat einige Zeit gedauert, bis ich deinen Code verstanden habe, aber jetzt ergibt das Sinn. Ich danke dir sehr. Ich habe es einfach auf einen größeren Datensatz angewendet und es funktioniert wie ein Zauber. – Sharath

Verwandte Themen