我希望创建一个累积平均值,平均多个群体的滞后时间。它用于预测分析,所以我希望每一行都是它之前所有行的累积平均值(不包括它自己的值)。
这是一个来自 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)
非常感谢任何帮助
答案 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
.. ... ... ...