2017-08-02 170 views
0

我有两个非常大的数据帧(5000万和150万),其中两个变量中的一些相同。我需要比较两者并在一个数据框中添加另一列,以便在另一个数据框中提供匹配观察值的计数。根据来自另一个数据帧的值计算一个数据帧中观察值的数量

例如:DF1和DF2都包含id,date,age_grp和性别变量。我想在DF1中添加另一列(match_count),其中显示了DF1.id = DF2.id和DF1.date = DF2.date和DF1.age_grp = DF2.age_grp和DF1.gender = DF2.gender 注意

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 

在上述示例的组合 “ID = 101,日期= 20140110,age_grp = 1,性别= 1”,在DF2中出现两次,因此计数2与组合 “ID = 102,日期= 20150010,age_grp = 2,性别= 2” 出现一次,因此计数1.

下面是所产生的数据帧我寻找

结果

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 

这里就是我此刻做,它工作得很好,包括小数据,但对于大数据不能很好地扩展。对于这个例子,即使几个小时后它也没有返回任何结果。

注:我已经通过this线消失了,它没有解决规模问题

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

的ID列是不是唯一的,因此可能有两个观察其中id,日期,agegrp和性别可能相同,只有val列可能不同。

回答

3

这里是什么,我会用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

我认为逻辑是要走的路,但为什么不去完整的dplyr并使用'left_join'而不是'merge'? – thelatemail

+0

@thelatemail我只是习惯合并..但是你是对的,我应该改变'合并'加入' – Wen

3

data.table可能会有所帮助这里也解决了这个问题。按指定的变量聚合DF2,然后将其加回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

感谢您的解决方案。请参阅更新。解决方案的问题是,如果有多个具有相同ID,日期,agegrp,性别和日期列的观察值,则计数将针对每个组合显示。所以观察'101 20140110 1 1 666'和'101 20140110 1 1 999'两者的计数都等于2.请建议 – Ali

相关问题