分组滚动平均值 R data.table

8

我想按组计算YTD滚动平均值,从组中的第一行开始到最后一行结束。以下是示例...

Group <- c(rep("a",5), rep("b",5))
Sales <- c(2,4,3,3,5,9,7,8,10,11)
Result <- c(2,3,3,3,3.4,9,8,8,8.5,9)
df <- data.frame(Group, Sales, Result)

结果列是我期望从滚动平均中看到的。

2个回答

16

使用cumsum

dt <- as.data.table(df)
dt[, res := cumsum(Sales)/(1:.N), by = Group]
dt
    Group Sales Result res
 1:     a     2    2.0 2.0
 2:     a     4    3.0 3.0
 3:     a     3    3.0 3.0
 4:     a     3    3.0 3.0
 5:     a     5    3.4 3.4
 6:     b     9    9.0 9.0
 7:     b     7    8.0 8.0
 8:     b     8    8.0 8.0
 9:     b    10    8.5 8.5
10:     b    11    9.0 9.0

或者使用 zoo 包中的 rollapplyr 函数:

dt[, res := rollapplyr(Sales, 1:.N, mean), by = Group]

或使用基础 R:

ave(df$Sales, df$Group, FUN = function(x) cumsum(x) / seq_along(x))

使用'rollapplyr'从'zoo'软件包:dt[, res := rollapplyr(Sales, 1:.N, mean), by = Group] (但是在我看来,你的更优雅) - Jaap
或者不使用额外的包:ave(df$Sales, df$Group, FUN = function(x) cumsum(x) / seq_along(x)) (注:此为R语言中的代码) - mtoto
@nachti 谢谢,我一直在尝试各种我找到的例子,但是我缺少的是 '1:.N'。 - MidnightDataGeek
我明白了。你也可以写成seq_len(.N)而不是1:.N(只是提供信息)。 - nachti

2
我们可以使用dplyrzoo%>%将lhs与rhs连接起来,非常容易理解和执行它。
library(dplyr)
library(zoo)
df %>%
   group_by(Group) %>% 
   mutate(Sales = rollapplyr(Sales, row_number(), mean))  
#    Group Sales Result
#    <fctr> <dbl>  <dbl>
#1       a   2.0    2.0
#2       a   3.0    3.0
#3       a   3.0    3.0
#4       a   3.0    3.0
#5       a   3.4    3.4
#6       b   9.0    9.0
#7       b   8.0    8.0
#8       b   8.0    8.0
#9       b   8.5    8.5
#10      b   9.0    9.0

1
是的,这很容易理解。我选择上面那个纯粹是因为我更经常使用数据表,这样可以保持我的代码一致性。 - MidnightDataGeek
2
@MidnightDataGeek 当然,使用data.table会更快。 - akrun

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