【问题标题】:Average the first row by group from data.table lookup从 data.table 查找中按组平均第一行
【发布时间】:2019-06-14 14:31:50
【问题描述】:

我希望为在指定日期之前出现的每个人平均最近的公司行。

换句话说,我想对每个人和每个日期的最近(每个公司)之前的 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 在 2018 年 1 月 2 日之前或 2018 年 1 月 2 日有 1 个实例,公司 62。因此,平均只有 1 个值,平均 alpha 为 1。

示例 2:

  • 2018-01-05 对个人 2 的观察。
  • 这里有个人 2 的 3 个观察值、公司 71 的 1 个观察值和公司 74 的 2 个观察值,因此我们为每个公司选择最近的观察值,这给我们留下了 2018-01-01 的 2 个观察结果 71 和 2018-01 的 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

【问题讨论】:

  • 从您的预期输出:我不明白为什么个人 1,公司 62,2018-01-04 之前的日期不是 (1+1.5)/2。我也不明白为什么个人 1,公司 63,在 2018-01-05 之前的日期是 (1.5+1)/2 而不是 1,它的唯一值。如果您详细说明您的需求,那么我们可以尝试提供帮助。
  • 非常感谢您的回复,正如我在问题中所说,我正在寻求平均每家公司的最近值。因此,对于个人 1,在 2018-01-04,公司 62 的最近一次是 1.5,公司 63 的值尚未出现。表 1 是基于个人的,因此我汇总了不止一家公司的(平均值),但仅使用最近值。抱歉,如果我没有说清楚。
  • 还是不清楚,抱歉帮不上忙:(
  • 我想为每个人和每个日期平均最近的先前 alpha 值。这更有意义吗?
  • 我可以解析“最近”和“每个日期”。我可以按日期或xyz 之前的日期来想象。不过别担心,我可能已经累了。也许其他人可以得到您的需求并提供答案

标签: r data.table


【解决方案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)]

【讨论】:

    【解决方案2】:
    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 的组合,所以我们将dates2 保留在dates 之前。按 date2 降序排列它们,因此我们可以通过每个 individual_idcompany_iddate 组合仅选择最近发生的事件(这就是 .SD[1,] 所做的)。

    之后,它只是按个人和日期计算平均值,并对表格进行排序以匹配您的预期输出。

    【讨论】:

    • 这看起来很有希望,我得等到星期一才能测试它。但是,使用大表可能会很困难吗?我的表 1 和 2 都超过 1m 行。
    猜你喜欢
    • 2019-09-22
    • 2022-11-16
    • 1970-01-01
    • 2019-07-26
    • 2014-06-30
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多