累积均值与分组和滞后

3
我希望创建一个累积平均值,它可以在多个组之间进行带有滞后的平均。这是为了预测分析,所以我希望每一行都是它之前所有行的累积平均值(不包括它自己的值)。
这是从Grouped moving average in r开始的一个跟进。
我相信可以使用rollapply和ave来实现这个目标,我已经使用下面的代码使用各种移动窗口实现了这个结果(只是不是累积平均值)。
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)

非常感谢任何帮助


1
使用 ave 函数,您想要的函数似乎是 function(x) c(NA, (cumsum(x) / seq_along(x))[-length(x)]) - alexis_laz
链接已添加,谢谢您告诉我。 - greeny
3个回答

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 放在那些使用 cumroll 时为 NA 的位置上:

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

3) 如果你想在这里使用rollapply,请注意可以在上述任意一种方式中用rollapplyr(x, seq_along(x), sum)替换cumsum

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))

谢谢,这很完美。 - greeny
你能帮忙扩展一下这个问题吗?非常感谢!http://stackoverflow.com/questions/35443059/cumulative-mean-with-conditions - greeny

4

一个选择是使用 data.table 进行分组,然后使用 dplyr 中的 cummean 函数:

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]

由于最后一个元素将被丢弃,但您将收到有关此的警告消息。


жИСиЃ§дЄЇдљ†еЇФиѓ•жПРеИ∞cummeanеЗљжХ∞жЭ•иЗ™dplyrеМЕгАВ - Jaap

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
..    ...   ...             ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接