2017-08-02 3 views
0

Ich habe zwei sehr große Datenrahmen (50 Millionen und 1,5 Millionen), wobei einige der Variablen in beiden identisch sind. Ich muss beide vergleichen und eine weitere Spalte in einem Datenrahmen hinzufügen, die die übereinstimmenden Beobachtungen in dem anderen Datenrahmen zählt.Anzahl der Beobachtungen in einem Datenrahmen basierend auf Werten aus einem anderen Datenrahmen

Zum Beispiel: DF1 und DF2 enthalten id, date, age_grp und gender-Variablen. Ich möchte eine weitere Spalte (match_count) in DF1 hinzufügen, die die Zählung zeigt, wo DF1.id = DF2.id und DF1.date = DF2.date und DF1.age_grp = DF2.age_grp und DF1.gender = DF2.gender Hinweis

DF1

id date age_grp gender val 
101 20140110 1 1  666 
102 20150310 2 2  777 
103 20160901 3 1  444 
104 20160903 4 1  555 
105 20010910 5 1  888 

DF2

id date age_grp gender state 
101 20140110 1 1  10 
101 20140110 1 1  12 
101 20140110 1 2  22 
102 20150310 2 2  33 

im obigen Beispiel der Kombination "id = 101, date = 20.140.110, age_grp = 1, gender = 1" erscheint zweimal in DF2 , daher die Zählung 2 und die Kombination "id = 102, date = 20.150.010, age_grp = 2, gender = 2" erscheint einmal, damit die Zählung 1.

Im Folgenden wird die resultierende Datenrahmen ich suche

Ergebnis

id date age_grp gender val match_count 
101 20140110 1 1  666 2 
102 20150310 2 2  777 1 
103 20160901 3 1  444 0 
104 20160903 4 1  555 0 
105 20010910 5 1  888 0 

Hier ist, was ich im Moment tue und es funktioniert sehr gut für kleine Daten aber nicht skaliert gut für große Daten. Für diesen Fall gab es auch nach mehreren Stunden keine Ergebnisse.

Anmerkung: Ich habe durch this Faden weg und es geht nicht auf die Waage Ausgabe

with(DF1 
    , mapply(
     function(arg_id,arg_agegrp, arg_gender, arg_date){ 
      sum(arg_id == DF2$id 
       & agegrp == DF2$agegrp 
       & gender_bool == DF2$gender 
       & arg_date == DF2$date) 
      }, 
    id, agegrp, gender, date) 
) 

UPDATE

der ID-Spalte nicht eindeutig ist, daher gibt es zwei Beobachtungen id wo sein könnte, Datum, Alter und Geschlecht können gleich sein und nur die Val-Spalte könnte unterschiedlich sein.

Antwort

3

Hier ist, was ich dieses Problem lösen wird dplyr

df2$state=NULL#noted you do not need column state 
Name=names(df2) 
df2=df2%>%group_by_(.dots=names(df2))%>%dplyr::summarise(match_count=n()) 
Target=merge(df1,df2,by.x=Name,by.y=Name,all.x=T) 
Target[is.na(Target)]=0 

Target 
    id  date age_grp gender val match_count 
1 101 20140110  1  1 666   2 
2 102 20150310  2  2 777   1 
3 103 20160901  3  1 444   0 
4 104 20160903  4  1 555   0 
5 105 20010910  5  1 888   0 
+1

Ich denke, die Logik ist der Weg zu gehen, aber warum nicht volle dplyr gehen und 'left_join' anstelle von' merge' verwenden? – thelatemail

+0

@thelatemail Ich gewöhne mich nur daran, zu fusionieren .. Aber du hast Recht, ich sollte die 'merge' zu ​​'Join' ändern – Wen

3

data.table mit Hilfe könnte auch hier hilfreich sein. Aggregieren Sie DF2 durch die angegebenen Variablen, dann verbinden Sie diese zurück zu DF1.

library(data.table) 
setDT(DF1) 
setDT(DF2) 

vars <- c("id","date","age_grp","gender") 
DF1[DF2[, .N, by=vars], count := N, on=vars] 
DF1 

# id  date age_grp gender val count 
#1: 101 20140110  1  1 666  2 
#2: 102 20150310  2  2 777  1 
#3: 103 20160901  3  1 444 NA 
#4: 104 20160903  4  1 555 NA 
#5: 105 20010910  5  1 888 NA 
+0

Danke für Ihre Lösung. Bitte beachten Sie das Update. Das Problem mit der Lösung besteht darin, dass, wenn es mehrere Beobachtungen gibt, die die gleiche ID-, Datums-, Altersgruppe, Geschlecht und Datumsspalte haben, die Zählung für jede Kombination erscheint. So werden die Beobachtungen '101 20140110 1 1 666' und' 101 201410110 1 1 999' beide gleich 2 zählen. Bitte schlagen Sie vor – Ali

Verwandte Themen