12

I would like to know how to calculate the cumulative average for some numbers. I will give a simple example to describe what I am looking for.

I have the following numbers

vec <- c(1, 2, 3, 4, 5)

If I do the average of these numbers I will get 3 as a result.

Now, how to do the cumulative average of these numbers.

Henrik
  • 65,555
  • 14
  • 143
  • 159
MR BIG
  • 163
  • 1
  • 1
  • 6

7 Answers7

22

In analogy to the cumulative sum of a list I propose this: The cumulative average avg of a vector x would contain the averages from 1st position till position i.

One method is just to compute the the mean for each position by summing over all previous values and dividing by their number.

By rewriting the definition of the arithmetic mean as a recursive formula. One gets

avg(1) = x(1)

and

avg(i) = (i-1)/i*avg(i-1) + x(i)/i;    (i > 1)

Evaluating this expression for every element of your vector (or list, one-dimensional array or however you call it) gives you the cumulative average.

This recursive method comes in handy if you have to calculate an average over very large or very many integers and would run into an overflow if you had to store their cumulative sum.

Example

In your example

1, 2, 3, 4, 5

we get

1, 1.5, 2, 2.5, 3
Marius
  • 651
  • 1
  • 6
  • 14
10

This is an old question and there have been lot of changes since then. I just thought of updating it with a dplyr answer. dplyr has a cummean function which directly gives the cumulative mean of the vector.

vec <- c(1, 2, 3, 4, 5)
library(dplyr)
cummean(vec)

#[1] 1.0 1.5 2.0 2.5 3.0
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
8

You can use the cumsum() function and the seq_along() function so read up on those. But the code provided make it clear. 6, 6 + 16, 6 + 16 + 8, and so on.

x <- sample(1:20)
x
# [1]  6 16  8  1 17 11  2 19 18  5 15 13  3 20  9 14  7 10 12  4
    
cumsum(x) / seq_along(x)
# [1]  6.000000 11.000000 10.000000  7.750000  9.600000  9.833333  8.714286
#10.000000 10.888889 10.300000
#[11] 10.727273 10.916667 10.307692 11.000000 10.866667 11.062500 10.823529
#10.777778 10.842105 10.500000
Maël
  • 45,206
  • 3
  • 29
  • 67
dxander
  • 99
  • 1
  • 5
5

Just keep a running sum of the numbers, and a running count of them. The average is just the sum over the count.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • Sorry, I would like to know how to do the cumulative average not the regular average. – MR BIG Jun 17 '12 at 21:09
  • 2
    Re-read the answer carefully - @Mike D has already explained how to do *cumulative* average. – Paul R Jun 17 '12 at 21:16
  • Does that mean in this case the Cumulative average should be 1 ?? which came from running sum of the numbers = 15 and the running count is also 15 ?? – MR BIG Jun 17 '12 at 21:22
  • 3
    @MRBIG: the running average goes 1/1, 3/2, 6/3, 10/4, 15/5, etc. unless I completely misunderstand what you mean by "cumulative average" – Mike Dunlavey Jun 18 '12 at 01:57
  • 1
    @Mike D: yes, that's all that a cumulative average is, i.e. it's just an average that you update every time you get a new data point. – Paul R Jun 18 '12 at 08:18
0
mynum
#[1] 1 2 3 4 5

cumsum(mynum)/seq(from=1, to=5)
#[1] 1.0 1.5 2.0 2.5 3.0
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
0

I made a simple C++ class.

#include <iostream>

using namespace std;

class Average {

public:
    Average(const double initVal=0.0){accumVal=initVal;}
    double getAverage(const double newVal) {

        accumVal += newVal;
        return accumVal / ++numAccumVal;
    }
    void clear(const double clearedVal=0.0) {

        accumVal = clearedVal;
        numAccumVal = 0;
    }
private:
    double accumVal;
    unsigned int numAccumVal=0;
};

int main(int argc, const char * argv[]) {

    Average avg;

    for (size_t i=1; i<=5; ++i) { //feed in 1 to 5

        double result = avg.getAverage(i);
        cout << "Result : " << result << endl; //print the result
    }
    return 0;
}

And if you run the code, you will get the result as below.

Result : 1
Result : 1.5
Result : 2
Result : 2.5
Result : 3
Program ended with exit code: 0
Zack Lee
  • 2,784
  • 6
  • 35
  • 77
-1

The question indicates serious lack of research but I don't have enough reputation yet to vote the question down. If I understand the question correctly, what is desired is the cumulative moving average.

Wikipedia describes cumulative moving average very clearly. I'm not allowed to post an image here but follow that link for a simple formula (a weighted average of the previous average and the new value).

Jam560
  • 101
  • 1
  • 5
  • 2
    Downvoted because not everyone knows how to translate math equations on Wikipedia to code, and your answer was little more than "let me google that for you." – Rokit Sep 10 '20 at 11:03