【问题标题】:Count number of observations in one data frame based on values from another data frame根据来自另一个数据帧的值计算一个数据帧中的观察数
【发布时间】:2018-01-09 02:08:53
【问题描述】:

我有两个非常大的数据框(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, date = 20140110, age_grp = 1, gender = 1”在 DF2 中出现了两次,因此计数为 2 和组合“id = 102, date = 20150010, age_grp = 2 , gender = 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)
)

更新

Id 列不是唯一的,因此可能有两个观察值,其中 id、date、agegrp 和 sex 可能相同,只有 val 列可能不同。

【问题讨论】:

    标签: r dataframe count aggregate


    【解决方案1】:

    这是我将使用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
    

    【讨论】:

    • 我认为逻辑是要走的路,但为什么不使用完整的 dplyr 并使用 left_join 而不是 merge
    • @thelatemail 我只是习惯了合并..但你是对的,我应该将merge 更改为join
    【解决方案2】:

    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
    

    【讨论】:

    • 感谢您的解决方案。请查看更新。该解决方案的问题在于,如果有多个观察值具有相同的 id、日期、agegrp、性别和日期列,则计数会针对每个组合出现。所以观察101 20140110 1 1 666101 20140110 1 1 999 的计数都将等于2。请建议
    猜你喜欢
    • 2018-04-27
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2018-02-12
    • 1970-01-01
    • 2021-01-26
    • 2013-06-14
    • 2019-07-10
    相关资源
    最近更新 更多