根据条件比较两个数据帧

时间:2016-07-29 01:56:49

标签: r plyr

我有两个数据框。 df1由各个用户的参数的平均大小组成。 df2包含用户相同参数的平均每日值。

我想计算每个 df2$size > df1$size user的事件的天数。

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)

预期输出为:

   user  count
AAL0706      2
AAN0823      1
AAV0450      2

我尝试使用以下命令来计算我的结果,但我发现有些问题。

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

请您告诉我一个有效的方法吗?

2 个答案:

答案 0 :(得分:1)

我们可以从left_join开始dplyr,按'用户'分组获取逻辑索引的sumsize.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

或使用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 :(得分:1)

使用data.table的一个稍微简单的解决方案是使用当前开发版本的data.table,v1.9.7中提供的新non-equi连接功能。

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

df1的每一行都根据df2参数提供的条件与on的所有行匹配,即匹配user的精确值并查看适用于size df2 user .N的所有行。

获取匹配的行(对于每一行),将为每一行计算表达式by = .EACHI(=匹配行的计数),因为j表示这一点。它指示执行提供给第二个参数i的表达式以运行每个 --(第一个参数)。

请参阅devel版本here的安装说明。