具有分组和滞后的累积均值

时间:2016-02-16 12:41:15

标签: r

我希望创建一个累积平均值,平均多个群体的滞后时间。它用于预测分析,所以我希望每一行都是它之前所有行的累积平均值(不包括它自己的值)。

这是一个来自 Grouped moving average in r

我确定有一种方法可以用rollapply和ave来做到这一点,我已经使用下面的各种移动窗口实现了这个结果(只是不是一个cummean):

library(zoo)

roll <- function(x, n) { 
   if (length(x) <= n) NA 
   else rollapply(x, list(-seq(n)), mean, fill = NA)
}
transform(DF, AVG2 = ave(Goals, Player, FUN = function(x) roll(x, 2)),
          AVG3 = ave(Goals, Player, FUN = function(x) roll(x, 3)))

这是所需的输出:

Player  Goals   **AVG**
S       5       
S       2       5
S       7       3.5
O       3       
O       9       3
O       6       6
O       3       6
S       7       4.66
O       1       5.25
S       7       5.25
S       3       5.6
Q       8       
S       3       5.16
O       4       4.4
P       1       
S       9       4.857
S       4       5.375
Z       6   
S       3       5.22
O       8       4.33
S       3       5
O       4       4.857
O       1       4.75
S       9       4.81
S       4       5.16
O       6       4.33
J       6   

以下是在r

中重新创建初始表的代码
Player <- c('S','S','S','O','O','O','O','S','O','S','S','O','S','O','O','S','S','O','S','O','S','O','O','S','S','O','J')
Goals <- c(5,2,7,3,9,6,3,7,1,7,3,8,3,4,1,9,4,6,3,8,3,4,1,9,4,6,6)
data.frame(Player, Goals)

非常感谢任何帮助

3 个答案:

答案 0 :(得分:5)

1)我们可以在R的基础上使用cumsum。不使用包。

cumroll <- function(x) {
  x <- head(x, -1)
  c(NA, cumsum(x) / seq_along(x))
}
transform(DF, AVG = ave(Goals, Player, FUN = cumroll))

2)这也可以取代cumroll。它将NaN放入NA cumroll

的帖子中
cumroll2 <- function(x) (cumsum(x) - x) / (seq_along(x) - 1)
transform(DF, AVG = ave(Goals, Player, FUN = cumroll2))

3)如果您确实想在此使用rollapply,请注意cumsum可以替换为rollapplyr(x, seq_along(x), sum)中的任何一个。

4)我们可以像rollapply这样使用cumroll2使用NaNs。

library(zoo)

cumroll3 <- function(x) {
  if (length(x) == 1) NaN
  else rollapply(x, lapply(seq_along(x) - 1, function(x) -seq_len(x)), mean)
}
transform(DF, AVG = ave(Goals, Player, FUN = cumroll3))

答案 1 :(得分:4)

一种选择是使用data.table进行分组,使用cummean函数来自dplyr

require(data.table)
require(dplyr)
Player <- c('S','S','S','O','O','O','O','S','O','S','S','O','S','O','O','S','S','O','S','O','S','O','O','S','S','O','J')
Goals <- c(5,2,7,3,9,6,3,7,1,7,3,8,3,4,1,9,4,6,3,8,3,4,1,9,4,6,6)
df<-data.frame(Player, Goals)

dt<-data.table(df)
lcummean<-function(x){
  head(c(NA,cummean(x)),-1)
}
dt[,ave:=lcummean(Goals),by=Player]

> dt
    Player Goals      ave
 1:      S     5       NA
 2:      S     2 5.000000
 3:      S     7 3.500000
 4:      O     3       NA
 5:      O     9 3.000000
 6:      O     6 6.000000
 7:      O     3 6.000000
 8:      S     7 4.666667
 9:      O     1 5.250000
10:      S     7 5.250000
11:      S     3 5.600000
12:      O     8 4.400000
13:      S     3 5.166667
14:      O     4 5.000000
15:      O     1 4.857143
16:      S     9 4.857143
17:      S     4 5.375000
18:      O     6 4.375000
19:      S     3 5.222222
20:      O     8 4.555556
21:      S     3 5.000000
22:      O     4 4.900000
23:      O     1 4.818182
24:      S     9 4.818182
25:      S     4 5.166667
26:      O     6 4.500000
27:      J     6       NA
    Player Goals      ave

如果你不介意警告信息,你也可以这样做:

dt[,ave:=c(NA,cummean(Goals)),by=Player]

因为最后一个元素将被丢弃,但你会收到有关它的警告信息。

答案 2 :(得分:3)

使用 dplyr cummean功能:

library(dplyr)
df1 %>% 
  group_by(Player) %>%
  mutate(mean_prev_goals = lag(cummean(Goals), n=1, default=0))

给出:

Source: local data frame [27 x 3]
Groups: Player [3]

   Player Goals mean_prev_goals
   (fctr) (dbl)           (dbl)
1       S     5        0.000000
2       S     2        5.000000
3       S     7        3.500000
4       O     3        0.000000
5       O     9        3.000000
6       O     6        6.000000
7       O     3        6.000000
8       S     7        4.666667
9       O     1        5.250000
10      S     7        5.250000
..    ...   ...             ...