首页 > 解决方案 > R中聚合结果的滚动平均值

问题描述

我有一个数据库,其中包含属于不同行业的各个公司的销售价值。在下面的示例数据集中:

set.seed(123)
df <- data.table(year=rep(1980:1984,each=4),sale=sample(100:150,20),ind=sample(LETTERS[1:2],20,replace = TRUE))
df[order(year,ind)]
    year sale ind
 1: 1980  114   A
 2: 1980  102   A
 3: 1980  130   B
 4: 1980  113   B
 5: 1981  136   A
 6: 1981  148   A
 7: 1981  141   B
 8: 1981  142   B
 9: 1982  124   A
10: 1982  125   A
11: 1982  104   A
12: 1982  126   B
13: 1983  108   A
14: 1983  128   A
15: 1983  140   B
16: 1983  127   B
17: 1984  134   A
18: 1984  107   A
19: 1984  106   A
20: 1984  146   B

“ind”列代表行业,我省略了公司标识符(在本例中没有用处)。我想要一个如下定义的平均值:

对于每一年,期望的平均值是过去三年行业内所有公司的平均值。如果过去三年的数据不可用,至少两次观察也是可以接受的。

例如,在上面的数据集中,如果 year=1982,ind=A,过去几年只有两个观察值(这仍然可以接受),所以期望的平均值是 1980 年和 1981 年所有销售值的平均值工业A。

如果 year=1983,ind=A,我们有三个前几年,并且期望的平均值是行业 A 在 1980 年、1981 年和 1982 年所有销售价值的平均值。

如果 year=1984 且 ind=A,我们有三个前几年,并且期望的平均值是行业 A 在 1981 年、1982 年和 1983 年所有销售价值的平均值。

因此,所需的输出将如下所示:

    year sale ind   mymean
 1: 1980  130   B       NA
 2: 1980  114   A       NA
 3: 1980  113   B       NA
 4: 1980  102   A       NA
 5: 1981  141   B       NA
 6: 1981  142   B       NA
 7: 1981  136   A       NA
 8: 1981  148   A       NA
 9: 1982  124   A 125.0000
10: 1982  125   A 125.0000
11: 1982  126   B 131.5000
12: 1982  104   A 125.0000
13: 1983  140   B 130.4000
14: 1983  127   B 130.4000
15: 1983  108   A 121.8571
16: 1983  128   A 121.8571
17: 1984  134   A 124.7143
18: 1984  107   A 124.7143
19: 1984  146   B 135.2000
20: 1984  106   A 124.7143

data.table 解决方案更适合快速实施。提前谢谢了。

标签: rdata.tablerolling-computationrolling-average

解决方案


我不是很擅长data.tabletidyverse如果您愿意,或者可以将其转换为 data.table,这是一种解决方案

library(tidyverse)

df %>% group_by(ind, year) %>% 
  summarise(ds = sum(sale),
            dn = n()) %>%
  mutate(ds = (lag(ds,1)+lag(ds,2)+ifelse(is.na(lag(ds,3)), 0, lag(ds,3)))/(lag(dn,1)+lag(dn,2)+ifelse(is.na(lag(dn,3)), 0, lag(dn,3)))
  ) %>% select(ind, year, mymean = ds) %>%
  right_join(df, by = c("ind", "year"))

`summarise()` regrouping output by 'ind' (override with `.groups` argument)
# A tibble: 20 x 4
   ind    year mymean  sale
   <chr> <int>  <dbl> <int>
 1 A      1980    NA    114
 2 A      1980    NA    102
 3 A      1981    NA    136
 4 A      1981    NA    148
 5 A      1982   125    124
 6 A      1982   125    125
 7 A      1982   125    104
 8 A      1983   122.   108
 9 A      1983   122.   128
10 A      1984   125.   134
11 A      1984   125.   107
12 A      1984   125.   106
13 B      1980    NA    130
14 B      1980    NA    113
15 B      1981    NA    141
16 B      1981    NA    142
17 B      1982   132.   126
18 B      1983   130.   140
19 B      1983   130.   127
20 B      1984   135.   146

推荐阅读