I’ve built a handful of reports for podcasters on SignalLeaf to see how large their audience is, how the audience is listening, etc. One report that I have been wanting to build for a while, though, needs to show the standard deviation for episode listens. That is, I want to show the listens for each episode and then show the average range in which those listens are falling. The resulting chart would look something like this:
According to Wikipedia, the most basic example of standard deviation is
found by taking the square root of the average of the squared differences of the values from their average value
The article goes on to show an example of how to calculate the standard deviation for a given data set:
- get the average value of the data set
- calculate the difference between each value in the set and the average
- then square the result of each difference
- average the squared differences
- get the square root of the average squared difference
There’s a lot more detail about this being a “population” standard deviation, and different forms of standard deviation, etc. But for me, this is good enough. I don’t really need to more any more detail than this. I have everything I need to get in to the code and calculate some stuff.
The reduce method allows me to iterate over the items in an array and produce a single result. In this case, I am producing a sum of all the items in the array… that is, I am reducing the values of the array down in to the sum of the values.
The next line divides the sum by the number of items in the array… the length of the array… the give me the average.
Now I need to calculate the difference between each of the values in the array, and the average value. To do that, I’m going to use the Array.prototype.map function.
The map function allows me to iterate over the items in an array, and return a new array of values that are calculated from the original array of values. The resulting array will be the same length as the original array, but it will contain the values that were calculated and returned from the callback of the .map call, instead of the original values. In this case, I am calculating the difference between the original values and the average of those values.
I also need to square the differences of each value as part of this process. Rather than running a second map over the differences, though, I will modify the previous map to return the square of the difference, instead of just the difference.
With the squared differences in hand, I need to get the average of these values. Again, I need to sum and divide the array – the same way I did it before. Only this time, I am creating the average of the squared differences instead of the average of the original values. Rather than repeat the code from above, I’ll extract that in to an “average” function:
And now I can run my average function to get the average squared difference:
Lastly, I need to calculate the square root of the average squared difference. This final result is the standard deviation for the data set from which I am calculating:
The Final Code
Putting it all together, the resulting code looks like this in one complete listing:
I can now run my standard deviation calculations by calling the “standardDeviation” function, passing in an array of numeric values.
Check out the working example in this JSFiddle, for the data set [1, 2, 3, 4, 5, 6, 7, 8, 9, 25]:
From here, I can apply the standard deviation to the average value.
Applying The Standard Deviation
Given the above data set, the average will be 7 with a standard deviation of 6.48.
The application of standard deviation is often shown as a +/- on top of an average. The +/- value is the standard deviation. Therefore, with the data set above, we can say that we have an average value of 7 with a standard deviation of +/- 6.48.
The result of this information is shown in the original chart from the top of this post
In this graph, the average is the solid yellow line through at the value of 7, while the standard deviation is shown with dashed lines on the upper and lower bounds: 7 – 6.48 for the lower bounds, and 7 + 6.48 for the upper bounds.
Array Map and Reduce
More Fun With Arrays
Looking for more fun things to do with arrays? Check out these episodes of WatchMeCode, where I walk through some of the interesting things that can be done with them!