0

Based on my values i need a function to get following results. enter image description here

The functions has to calculate the mean of current value and the 3 previous values. The function should be flexible in that way, that the same calculation can be applied for 2, 4, 5 or x previous values, for example: mean of current value and the 2 previous values.

please consider, that my daten has random numbers, and not like in above example ascending numbers

flobrr
  • 197
  • 1
  • 2
  • 13
  • 5
    What have you already attempted? This site isn't somewhere to have other people do your work for you without trying first. – DataTx Jan 23 '18 at 13:46
  • I handled it with excel, cause i am a newbee in R. I think this task is a good exercise for me to get an fundmental understanding of how R works. – flobrr Jan 23 '18 at 13:55
  • @flobrr I'd like to know why you unaccepted my answer today. I was first, I expanded it providing two alternatives (using two very well-known packages), I followed up all your comments/doubts immediately and the other answer did not provide any substantial improvement and used the dummy data I provided and approach with dplyr and mutate. Thanks. – mpalanco Jan 24 '18 at 09:22
  • sorry, i did not recognize only one answer can be accepted. I gave you the one and only "accepted" now. – flobrr Jan 24 '18 at 09:44
  • @flobrr Thank you. – mpalanco Jan 24 '18 at 09:55

2 Answers2

3

What you need is a rolling mean, in the argument k (4 in my example) you provide an integer width of the rolling window. Check the documentation page for the rollmean function of the zoo package, ?rollmean.

zoo

library(zoo) 
library(dplyr)
df <- data.frame(number = 1:20)
  df %>% mutate(rolling_avg = rollmean(number, k = 4 , fill = NA, align = "right"))

RcppRoll

library(RcppRoll)
df %>% mutate(rolling_avg = roll_mean(number, n = 4, fill = NA, align = "right"))

Output

   number rolling_avg
1       1          NA
2       2          NA
3       3          NA
4       4         2.5
5       5         3.5
6       6         4.5
7       7         5.5
8       8         6.5
9       9         7.5
10     10         8.5
11     11         9.5
12     12        10.5
13     13        11.5
14     14        12.5
15     15        13.5
16     16        14.5
17     17        15.5
18     18        16.5
19     19        17.5
20     20        18.5

Using the other vector you provided in the comments:

  df <- data.frame(number = c(1,-3,5,4,3,2,-4,5,6,-4,3,2,3,-4,5,6,6,3,2))
  df %>% mutate(rolling_avg = rollmean(number, 4, fill = NA, align = "right"))

Output

   number rolling_avg
1       1          NA
2      -3          NA
3       5          NA
4       4        1.75
5       3        2.25
6       2        3.50
7      -4        1.25
8       5        1.50
9       6        2.25
10     -4        0.75
11      3        2.50
12      2        1.75
13      3        1.00
14     -4        1.00
15      5        1.50
16      6        2.50
17      6        3.25
18      3        5.00
19      2        4.25
mpalanco
  • 12,960
  • 2
  • 59
  • 67
  • please consider, that my daten has random numbers, and not like in above example ascending numbers, for example (1,-3,5,4,3,2,-4,5,6,-4,3,2,3,-4,5,6,6,3,2) – flobrr Jan 23 '18 at 14:13
  • @flobrr Then you would need to sort the data as desired before applying the rollmean function. Without providing a reproducible example, this is the best we can do.[How to make a great R reproducible example?](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – mpalanco Jan 23 '18 at 14:19
  • dont understand why i should sort the data "as desired"? The data is desired as it occours, this is my data: (1,-3,5,4,3,2,-4,5,6,-4,3,2,3,-4,5,6,6,3,2). and the first result i wanna get is (1-3+5+4)/4. Sorting my data would change it. – flobrr Jan 23 '18 at 14:31
  • @flobrr Then I do not understand your first comment clarifying that your data is not in ascending order. The code should work as it is then. – mpalanco Jan 23 '18 at 14:40
  • ok, in my screenshot i have a data example with ascending numbers, but this is just an simplified example. My real data are not ascending numbers. your code works with ascending numbers, but not with these data: (1,-3,5,4,3,2,-4,5,6,-4,3,2,3,-4,5,6,6,3,2). – flobrr Jan 23 '18 at 14:44
  • @flobrr I included your vector in the answer. It works perfectly fine. Maybe we misunderstood your question. – mpalanco Jan 23 '18 at 14:49
1

You can also use the rollify function in the tibbletime package to create a custom rolling function for any function. For mean it would look like this (using data from @mpalanco's answer):

library(dplyr)
library(tibbletime)

rolling_mean <- rollify(mean, window = 4)

df %>% mutate(moving_average = rolling_mean(number))

which gives you:

   number moving_average
1       1             NA
2       2             NA
3       3             NA
4       4            2.5
5       5            3.5
6       6            4.5
7       7            5.5
8       8            6.5
9       9            7.5
10     10            8.5
11     11            9.5
12     12           10.5
13     13           11.5
14     14           12.5
15     15           13.5
16     16           14.5
17     17           15.5
18     18           16.5
19     19           17.5
20     20           18.5

The benefit of this approach is that it is easy to extend to things other than rolling average.

tbradley
  • 2,210
  • 11
  • 20