从data.table查找中按组平均第一行

时间:2019-06-14 14:31:50

标签: r data.table

我希望对在指定日期之前发生的每个个人的最新公司行进行平均。

换句话说,我想平均每个人和每个日期的最新(每个公司)以前的alpha值。

table1 <- fread(
  "individual_id | date       
       1             |  2018-01-02
       1             |  2018-01-04
       1             |  2018-01-05
       2             |  2018-01-02
       2             |  2018-01-05", 
  sep ="|"
)
table1$date = as.IDate(table1$date)
table2 <- fread(
  "individual_id | date2       | company_id | alpha
       1             |  2018-01-02 |     62       |  1     
       1             |  2018-01-04 |     62       |  1.5 
       1             |  2018-01-05 |     63       |  1   
       2             |  2018-01-01 |     71       |  2     
       2             |  2018-01-02 |     74       |  1   
       2             |  2018-01-05 |     74       |  4",
  sep = "|"
)

例如:

  • 表1中的观测值1在2018-01-02上是单独的“ 1”。
  • 要实现这一目标,我在表2中看到,个人1拥有一个实例prio或公司62在2018年1月2日。因此,平均值只有1个值,平均alpha为1。

示例2:

  • 2018年2月5日个人2的观测结果。
  • 这里对于个人2有3个观察值,对公司71有1个观察值,对于公司74有2个观察值,所以我们选择了每个公司的最新观察值,这给我们留下了2018年1月1日的2个观察值71和2018年1月的74 -05,alpha值为2和4,则平均alpha为3。

结果应如下所示:

table1 <- fread(
      "individual_id | date         | mean alpha
       1             |  2018-01-02  | 1
       1             |  2018-01-04  | 1.5
       1             |  2018-01-05  | (1.5+1)/2 = 1.25
       2             |  2018-01-02  | (2+1)/2 = 1.5
       2             |  2018-01-05  | (2+4)/2 = 3", 
      sep ="|"
    )

我可以使用以下命令从table2中获得第一行的子样本:

table2[, .SD[1], by=company_id]

但是我不确定如何限制日期,并将其与第一个表格结合起来。

修改

这会为每个人(而不是公司)生成结果。

table1[, mean_alpha := 
         table2[.SD, on=.(individual_id, date2 <= date), mean(alpha, na.rm = TRUE), by=.EACHI]$V1]


individual_id    date    mean_alpha
1   2018-01-02  1.000000
1   2018-01-04  1.250000
1   2018-01-05  1.166667
2   2018-01-02  1.500000
2   2018-01-05  2.333333

2 个答案:

答案 0 :(得分:1)

table2[table1, 
       on = "individual_id", 
       allow.cartesian = TRUE][
         date2 <= date, ][order(-date2)][, 
           .SD[1,], 
           by = .(individual_id, company_id, date)][, 
                     mean(alpha), 
                     by = .(individual_id, date)][
  order(individual_id, date)]

我在那里所做的:将表1和2单独连接在一起,允许所有可能的组合。然后过滤掉date2大于date的组合,因此我们将date2保留在日期之前。按date2按降序对它们进行排序,因此我们可以按.SD[1,]individual_idcompany_id的组合仅选择最近出现的事件(这就是date的结果)。 / p>

此后,它仅按个人和日期计算平均值,然后对表格进行排序以与您的预期输出匹配。

答案 1 :(得分:1)

这是另一种可能的方法:

#ensure that order is correct before using the most recent for each company
setorder(table2, individual_id, company_id, date2)

table1[, mean_alpha := 
    #perform non-equi join
    table2[table1, on=.(individual_id, date2<=date), 
        #for each row of table1,
        by=.EACHI,
        #get most recent alpha by company_id and average the alphas
        mean(.SD[, last(alpha), by=.(company_id)]$V1)]$V1
    ]

输出:

   individual_id       date mean_alpha
1:             1 2018-01-02       1.00
2:             1 2018-01-04       1.50
3:             1 2018-01-05       1.25
4:             2 2018-01-02       1.50
5:             2 2018-01-05       3.00

数据:

library(data.table)
table1 <- fread(
    "individual_id | date       
       1             |  2018-01-02
       1             |  2018-01-04
       1             |  2018-01-05
       2             |  2018-01-02
       2             |  2018-01-05", 
    sep ="|"
)
table1[, date := as.IDate(date)]
table2 <- fread(
    "individual_id | date2       | company_id | alpha
       1             |  2018-01-02 |     62       |  1     
       1             |  2018-01-04 |     62       |  1.5 
       1             |  2018-01-05 |     63       |  1   
       2             |  2018-01-01 |     71       |  2     
       2             |  2018-01-02 |     74       |  1   
       2             |  2018-01-05 |     74       |  4",
    sep = "|"
)
table2[, date2 := as.IDate(date2)]