2016-08-25 9 views
6

Ich versuche, zwei Datenrahmen nach mehreren Kriterien zu suchen und zusammenzufassen, und habe viele Schwierigkeiten damit, es zu verstehen.Wie erstelle ich einen Multiple-Criteria-Index in R mit> und <Operatoren?

ich zwei Sätze von Daten haben, den ich bin auf der Suche nach Index dagegen die Gültigkeitsdaten von einigen Produkten und die andere enthält, die mich Produktverwendung gibt, wie folgt:

Indexset <- data.table(validfrom=as.Date(c("2015-08-01", "2015-08-02", "2015-08-03", "2015-08-04")), 
         validto=as.Date(c("2015-08-07", "2015-08-08","2015-08-09", "2015-08-10")), 
         username=c("Smith", "Cole", "Amos", "Richardson"), 
         productcode=c(1,2,3,4)) 

    Useset <- data.table(usedate=as.Date(c("2015-08-04", "2015-08-06", "2015-08-06", "2015-08-09")), 
        username=c("Smith", "Richardson", "Cole", "Amos")) 

Was ich Ich versuche zu tun ist eine Spalte zu Useset hinzufügen, die den "Produktcode" von "Indexset" enthalten wird, indem Sie überprüfen, die "Usedate" ist zwischen den 'gültig' & 'Gültig ab' Daten und dann den Namen übereinstimmen.

Ich habe verschiedene Möglichkeiten um die "merge" -Funktion versucht, konnte aber nicht herausfinden, wie die Größer als und kleiner als Operatoren in die Syntax zu bekommen.

Haben auch versucht, Einstellung und Rolling Joins aber kämpfen, um sie zum Funktionieren zu bringen.

Zur Zeit von Excel Migration, wo dies nur eine mehrere Kriterien Indexanpassung in einem Array sein würde, aber nicht sicher, wie es in R., um gemeinsam

klar sein, ich bin nicht Fehler schlagen, nur völlig verloren indem wir die Syntax zusammenfügen.

Sobald ich die "Produktcodes" habe ich denke, ich kann mit der Zusammenführung umgehen, aber absolut ratlos hier!

Würde mich über jede Hilfe freuen, die jemand anbieten kann!

+1

In der neuen Version von 'Daten. table', können Sie das tun, oder eine andere Option ist 'foverlaps' – akrun

+1

Wenn Ihre Indexmenge alle Zeitintervalle abdeckt, in denen eine Person erscheinen könnte, dann ...' Useset [, v: = Indexset [Useset, on = c (" benutzername ", validfrom =" usedate "), roll = TRUE] $ productcode]' sollte sogar auf 1.9.6 funktionieren, denke ich. Es ist eine unangenehme Art, einen rollenden Join zu verwenden, nicht sicher, ob es einen besseren Weg gibt. – Frank

Antwort

5

Sie können versuchen, die non-equi Join-Funktion aus der aktuellen Entwicklungsversion von data.table, v1.9.7. Bitte lesen Sie die Installationsanleitung here.

Useset[Indexset, on = .(username, usedate >= validfrom, usedate <= validto), # which rows? 
     productcode := productcode][]          # what to do? 

#  usedate username productcode 
# 1: 2015-08-01  Smith   1 
# 2: 2015-08-04 Richardson   4 
# 3: 2015-08-02  Cole   2 
# 4: 2015-08-03  Amos   3 

Usenet wird in-place aktualisiert.


Wenn die Leistung kein großes Problem ist, auf username beitreten und dann filtern soll auch funktionieren, dies erfordert nicht die Entwickler-Version von data.table:

Useset[Indexset, on = "username"][usedate >= validfrom & usedate <= validto, .(usedate, username, productcode)] 
#  usedate username productcode 
# 1: 2015-08-01  Smith   1 
# 2: 2015-08-02  Cole   2 
# 3: 2015-08-03  Amos   3 
# 4: 2015-08-04 Richardson   4 
+1

Psidom, sehr nette Antwort! Einige (geringfügige) Änderungen vorgenommen (mit Erläuterung in der Bearbeitungshistorie). Fühlen Sie sich frei, Rollback. – Arun

+1

In Ihrer zweiten Lösung könnte es besser sein, klarzustellen, dass Sie "Speicher" nach Leistung meinen (da die Anzahl der übereinstimmenden Zeilen durch "Benutzername" allein explodieren könnte). – Arun

+1

@Arun danke. Ich denke, das sind gute Bearbeitungen, die es den Leuten erleichtern, die Ressourcen zu finden. – Psidom