2016-07-29 13 views
2

Ich habe folgende zwei Datenrahmen. df1 besteht aus einer durchschnittlichen Größe eines Parameters für einzelne Benutzer. df2 enthält den durchschnittlichen Tageswert für denselben Parameter für Benutzer.Vergleichen zweier Datenrahmen basierend auf einer Bedingung

Ich möchte die Anzahl der Tage für die Ereignisse zählen, wo df2$size > df1$size für jederuser.

df1 = read.table(text='user size 
AAL0706 29000 
AAN0823 25000 
AAV0450 30000', stringsAsFactors=FALSE, header=TRUE) 


df2 = read.table(text='Date user size 
     2010-01-04 AAL0706 31054 
     2010-01-06 AAL0706 20703 
     2010-01-08 AAL0706 39968 
     2010-01-04 AAN0823 17892 
     2010-01-06 AAN0823 37839 
     2010-01-08 AAN0823 19649 
     2010-01-04 AAV0450 35432 
     2010-01-06 AAV0450 37839', stringsAsFactors=FALSE, header=TRUE) 

Erwartete Ausgabe lautet:

user count 
AAL0706  2 
AAN0823  1 
AAV0450  2 

Ich habe versucht, den folgenden Befehl zu verwenden, um meine Ergebnisse zu berechnen, aber ich merke, etwas nicht stimmt.

lapply(df1, function(y) { 
    ddply(df2$size, .(user), function(x) { 
     return(length(y$size(y$size > x$size)) 
    }) 
}) 

Könnten Sie mir bitte einen effizienten Weg geben, dies zu tun?

Antwort

1

können wir tun, ein left_join von dplyr, gruppiert nach 'user' die sum von logischen Index erhalten (size.x > size.y)

library(dplyr) 
left_join(df2, df1, by = "user") %>% 
      group_by(user) %>% 
      summarise(Count = sum(size.x > size.y)) 
#  user Count 
#  <chr> <int> 
#1 AAL0706  2 
#2 AAN0823  1 
#3 AAV0450  2 

Oder mit data.table

library(data.table) 
setDT(df2)[df1, .(count = sum(size > i.size)),on = "user", by = .EACHI] 
#  user count 
#1: AAL0706  2 
#2: AAN0823  1 
#3: AAV0450  2 
+1

Die Verwendung von "dplyr" -Bibliothek war hilfreich für mich beim Ersetzen der meisten meiner Arbeit mit "Aggregat" -Funktion. Ich habe mit Speicherproblemen mit "Aggregat" -Funktion bei der Verarbeitung großer Datensätze gekämpft. Ich glaube "dplyr" Paket war eine gute Alternative für mein Problem – Anna

1

Eine etwas einfachere Lösung, die data.table verwendet, würde sein, die neue Join-Funktion non-equi zu verwenden, die in dem c verfügbar ist aktuelle Entwicklungsversion von data.table, v1.9.7.

require(data.table) 
setDT(df2)[df1, .N, on=.(user, size > size), by=.EACHI] 

Jede Reihe von df1 ist gegen alle Reihen von df2 abgestimmt auf der Grundlage des für das Argument on vorgesehen Zustand, das heißt Übereinstimmung für genauen Wert von user und für alle Zeilen suchen, wo size von df2 größer ist innerhalb dass user.

Sobald die übereinstimmenden Zeilen erhalten sind (für jede Zeile), wird der Ausdruck .N (= Anzahl der übereinstimmenden Zeilen) für jede Zeile ausgewertet, da by = .EACHI dies beinhaltet. Er weist an, dass der Ausdruck, der für das zweite Argument j bereitgestellt wird, für jeweilsi ausgeführt wird (das erste Argument).

Siehe Installationsanleitung für die Entwicklungsversion here.

Verwandte Themen