如何在缺少组合时按组计算平均值

时间:2016-02-16 15:14:57

标签: r data.table

我有一个包含两个键(def f(s): return 'c' not in s newlist = filter(f, L) ID)的数据集,用于多个日期。 我想按月计算Cells的平均值。问题是某些MM - ID组合中缺少某些日期,但我每天可以使用一个Cells,所以这不是问题。

我所做的是创建一个包含唯一日期的新数据表,计算MM的平均值,然后将其与原始数据表合并,然后删除重复的列。

显然,效率不高。还有其他办法吗?

可重复的例子:

MM

2 个答案:

答案 0 :(得分:1)

您可以做的是使用DATEID上的交叉联接作为i中的参考,以添加缺少的DATE / ID组合,然后计算平均值:

DT[CJ(DATE, ID, unique = TRUE), on=c(DATE="V1", ID="V2")
   ][, AverageMM := sum(MM, na.rm = TRUE)/.N, by = .(year(DATE), month(DATE))][]

给出:

          DATE ID Cells  MM Year Month Day AverageMM
 1: 2000-01-01  1     1 100 2000     1   1     200.0
 2: 2000-01-01  2    10 100 2000     1   1     200.0
 3: 2000-01-02  1     2 200 2000     1   2     200.0
 4: 2000-01-02  2    20 200 2000     1   2     200.0
 5: 2000-01-03  1     3 300 2000     1   3     200.0
 6: 2000-01-03  2    30 300 2000     1   3     200.0
 7: 2000-01-04  1    NA  NA   NA    NA  NA     200.0
 8: 2000-01-04  2    40 400 2000     1   4     200.0
 9: 2000-02-01  1     1 500 2000     2   1     487.5
10: 2000-02-01  2    10 500 2000     2   1     487.5
11: 2000-02-02  1     2 600 2000     2   2     487.5
12: 2000-02-02  2    NA  NA   NA    NA  NA     487.5
13: 2000-02-03  1    NA  NA   NA    NA  NA     487.5
14: 2000-02-03  2    30 700 2000     2   3     487.5
15: 2000-02-04  1     4 800 2000     2   4     487.5
16: 2000-02-04  2    40 800 2000     2   4     487.5

另一种可能性是使用 tidyr 包中的DATE函数添加缺少的ID / complete组合:

library(tidyr)
setDT(complete(DT,DATE,ID))[, AverageMM := sum(MM, na.rm = TRUE)/.N, by = .(year(DATE), month(DATE))][]

会给你相同的输出。

答案 1 :(得分:1)

你可以......

DT[, aveMM := weighted.mean(MM, !duplicated(DATE)), by=.(year(DATE), month(DATE))]

给出了

          DATE ID Cells  MM AveMM
 1: 2000-01-01  1     1 100   250
 2: 2000-01-02  1     2 200   250
 3: 2000-01-03  1     3 300   250
 4: 2000-01-01  2    10 100   250
 5: 2000-01-02  2    20 200   250
 6: 2000-01-03  2    30 300   250
 7: 2000-01-04  2    40 400   250
 8: 2000-02-01  1     1 500   650
 9: 2000-02-02  1     2 600   650
10: 2000-02-04  1     4 800   650
11: 2000-02-01  2    10 500   650
12: 2000-02-03  2    30 700   650
13: 2000-02-04  2    40 800   650

这为重复的天赋予零权重。

要扩展到mean以外的功能,这样的方法有效:

DT[, AveMM := mean(tapply(MM, DATE, head, 1)), by=.(year(DATE), month(DATE))]

但是,它不是很好的数据。表格。