7
votes

I got a data.frame ABC_Score.

ABC_Score <- data.frame(Level = c("A", "A", "A", "B", "B", "C", "C", 
"C", "C"), result = c(2, 3, 3, 7, 9, 18, 20, 17, 20))

What I need is the moving average of the result per Level.

Currently I have the moving average with the following script.

install.packages("TTR")
library(TTR)

`ABC_Score$MA` <- runMean(ABC_Score$result, 2)

      Level result   MA
    1     A      2   NA
    2     A      3  2.5
    3     A      3  3.0
    4     B      7  5.0
    5     B      9  8.0
    6     C     18 13.5
    7     C     20 19.0
    8     C     17 18.5
    9     C     20 18.5

but here I need to specify the number of rows (result) where the moving average will be calculated over. In this example 2 which is incorrect since results from different Levels are now mixed in the moving average.

How can the moving average automatically be calculated over the result per Level?

2
have you looked at by and zoo::rollmean?r2evans

2 Answers

10
votes

You could use group_by and mutate from dplyr.

library(TTR)
library(dplyr)
ABC_Score <- data.frame(
    Level = c("A", "A", "A", "B", "B", "C", "C", "C", "C"), 
    result = c(2, 3, 3, 7, 9, 18, 20, 17, 20))
ABC_Score %>% group_by(Level) %>% mutate(ra = runMean(result, 2))
# A tibble: 9 x 3
# Groups:   Level [3]
   Level result    ra
  <fctr>  <dbl> <dbl>
1      A      2    NA
2      A      3   2.5
3      A      3   3.0
4      B      7    NA
5      B      9   8.0
6      C     18    NA
7      C     20  19.0
8      C     17  18.5
9      C     20  18.5
2
votes

Using function on sinbgle vectors with levels of a factor is what the ave function does:

 ABC_Score$MA <- with(ABC_Score, ave(result, Level, FUN=function(x) 
                     TTR::runMean(x, n=2)) )
> ABC_Score
  Level result   MA
1     A      2   NA
2     A      3  2.5
3     A      3  3.0
4     B      7   NA
5     B      9  8.0
6     C     18   NA
7     C     20 19.0
8     C     17 18.5
9     C     20 18.5