2

我想为 alpha、bravo 和 charlie(以及许多其他变量)创建一个滚动 2 个季度的平均值。研究将我带到动物园并润滑包裹,但似乎总是回到一个变量或分组内滚动

set.seed(123)

dates <-  c("Q4'15", "Q1'16", "Q2'16","Q3'16", "Q4'16", "Q1'17", "Q2'17" ,"Q3'17", "Q4'17","Q1'18")

df <- data.frame(dates = sample(dates, 100,  replace = TRUE, prob=rep(c(.03,.07,.03,.08, .05),2)), 
                           alpha = rnorm(100, 5), bravo = rnorm(100, 10), charlie = rnorm(100, 15))

我正在寻找类似的东西

x <- df %>% mutate_if(is.numeric, funs(rollmean(., 2, align='right', fill=NA)))

期望的结果:每列数据(alpha、bravo、charlie)的“Q4'15”和“Q1'16”、“Q1'16”和“Q2'16”等的加权平均值。不寻找配对季度平均值的平均值。

这是 Q4'15 和“Q1'16”时间点的平均值

df %>% filter(dates %in% c("Q4'15", "Q1'16")) %>%  select(-dates) %>% summarise_all(mean)
4

1 回答 1

3

我喜欢data.table这个,我有一个解决方案给你,但可能有一个更优雅的解决方案。这是我所拥有的:

数据

现在作为data.table

R> suppressMessages(library(data.table))
R> set.seed(123)
R> datesvec <- c("Q4'15", "Q1'16", "Q2'16","Q3'16", "Q4'16",
+               "Q1'17", "Q2'17" ,"Q3'17", "Q4'17","Q1'18")
R> df <- data.table(dates = sample(dates, 100,  replace = TRUE,
+                                 prob=rep(c(.03,.07,.03,.08, .05),2)),
+                  alpha = rnorm(100, 5),
+                  bravo = rnorm(100, 10),
+                  charlie = rnorm(100, 15))
R> df[ , ind := which(datesvec==dates), by=dates]
R> setkey(df, ind)  # optional but may as well
R> head(df)
   dates   alpha    bravo charlie ind
1: Q4'15 5.37964 11.05271 14.4789   1
2: Q4'15 7.05008 10.36896 15.0892   1
3: Q4'15 4.29080 12.12845 13.6047   1
4: Q4'15 5.00576  8.93667 13.3325   1
5: Q4'15 3.53936  9.81707 13.6360   1
6: Q1'16 3.45125 10.56299 16.0808   2
R> 

这里的关键是我们需要恢复/维护您的数据表示没有的季度的时间顺序。

按季度平均

这很容易data.table

R> ndf <- df[ ,
+           .(qtr=head(dates,1),          # label of quarter
+             sa=sum(alpha),              # sum of a in quarter
+             sb=sum(bravo),              # sum of b in quarter
+             sc=sum(charlie),            # sum of c in quarter
+             n=.N),                      # number of observations
+           by=ind]
R> ndf
    ind   qtr      sa       sb       sc  n
 1:   1 Q4'15 25.2656  52.3039  70.1413  5
 2:   2 Q1'16 65.8562 132.6650 192.7921 13
 3:   3 Q2'16 10.3422  17.8061  31.3404  2
 4:   4 Q3'16 84.6664 168.1914 256.9010 17
 5:   5 Q4'16 41.3268  87.8253 139.5873  9
 6:   6 Q1'17 42.6196  85.4059 134.8205  9
 7:   7 Q2'17 76.5190 162.0784 241.2597 16
 8:   8 Q3'17 42.8254  83.2483 127.2600  8
 9:   9 Q4'17 68.1357 133.5794 198.1920 13
10:  10 Q1'18 37.0685  78.4107 120.2808  8
R> 

滞后这些平均值一次

R> ndf[, `:=`(psa=shift(sa),               # previous sum of a
+            psb=shift(sb),               # previous sum of b
+            psc=shift(sc),                # previous sum of c
+            pn=shift(n))]                # previous nb of obs
R> ndf
    ind   qtr      sa       sb       sc  n     psa      psb      psc pn
 1:   1 Q4'15 25.2656  52.3039  70.1413  5      NA       NA       NA NA
 2:   2 Q1'16 65.8562 132.6650 192.7921 13 25.2656  52.3039  70.1413  5
 3:   3 Q2'16 10.3422  17.8061  31.3404  2 65.8562 132.6650 192.7921 13
 4:   4 Q3'16 84.6664 168.1914 256.9010 17 10.3422  17.8061  31.3404  2
 5:   5 Q4'16 41.3268  87.8253 139.5873  9 84.6664 168.1914 256.9010 17
 6:   6 Q1'17 42.6196  85.4059 134.8205  9 41.3268  87.8253 139.5873  9
 7:   7 Q2'17 76.5190 162.0784 241.2597 16 42.6196  85.4059 134.8205  9
 8:   8 Q3'17 42.8254  83.2483 127.2600  8 76.5190 162.0784 241.2597 16
 9:   9 Q4'17 68.1357 133.5794 198.1920 13 42.8254  83.2483 127.2600  8
10:  10 Q1'18 37.0685  78.4107 120.2808  8 68.1357 133.5794 198.1920 13
R> 

当前和上一季度的平均值

R> ndf[is.finite(psa),                     # where we have valid data
+     `:=`(ra=(sa+psa)/(n+pn),            # total sum / total n == avg
+          rb=(sb+psb)/(n+pn),
+          rc=(sc+psc)/(n+pn))]
R> ndf[,c(1:2, 11:13)]
    ind   qtr      ra       rb      rc
 1:   1 Q4'15      NA       NA      NA
 2:   2 Q1'16 5.06233 10.27605 14.6074
 3:   3 Q2'16 5.07989 10.03141 14.9422
 4:   4 Q3'16 5.00045  9.78935 15.1706
 5:   5 Q4'16 4.84589  9.84680 15.2496
 6:   6 Q1'17 4.66369  9.62395 15.2449
 7:   7 Q2'17 4.76554  9.89937 15.0432
 8:   8 Q3'17 4.97268 10.22195 15.3550
 9:   9 Q4'17 5.28386 10.32513 15.4977
10:  10 Q1'18 5.00972 10.09476 15.1654
R> 

利用两个季度的总和除以观察总数与这两个季度的平均值相同的事实。(这反映了我之前的想法之后的编辑)。

突击检查

我们可以使用 的选择功能data.table来手动计算其中的两行,我选择了那些作为索引<1,2><4,5>在这里:

R> df[ ind <= 2, .(a=mean(alpha), b=mean(bravo), c=mean(charlie))]
         a      b       c
1: 5.06233 10.276 14.6074
R> df[ ind == 4 | ind == 5, .(a=mean(alpha), b=mean(bravo), c=mean(charlie))]
         a      b       c
1: 4.84589 9.8468 15.2496
R> 

这很好,并且由于data.table.

PS:一体机

正如您提到的管道等,您可以data.table使用链式操作编写所有这些。不是我喜欢的风格,但可能。以下创建完全相同的输出,而无需ndf像上面那样创建临时:

## All in one
df[ , ind := which(datesvec==dates), by=dates][
   ,
    .(qtr=head(dates,1),          # label of quarter
      sa=sum(alpha),              # sum of a in quarter
      sb=sum(bravo),              # sum of b in quarter
      sc=sum(charlie),            # sum of c in quarter
      n=.N),                      # number of observations
    by=ind][
   ,
    `:=`(psa=shift(sa),               # previous sum of a
         psb=shift(sb),               # previous sum of b
         psc=shift(sc),                # previous sum of c
         pn=shift(n))][
    is.finite(psa),                     # where we have valid data
    `:=`(ra=(sa+psa)/(n+pn),            # total sum / total n == avg
         rb=(sb+psb)/(n+pn),
         rc=(sc+psc)/(n+pn))][
    ,c(1:2, 11:13)][]
于 2018-06-09T20:33:22.433 回答