using System; using System.Collections.Generic; namespace MathLib { ////// Container class for all statistics values which may be set by the Statistics class /// public class StatTypes { public double? Average { get; set; } public double? StdDev { get; set; } } public static class Statistics { ////// Gets the average and standard deviation of a set in one pass /// /// The set to be operated on ///A StatTypes object with the Average and StdDev values /// for the set operated on public static StatTypes GetAvgAndStdDev(this IEnumerable<double> values) { StatTypes avgAndStdDev = new StatTypes(); // ref: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/ double mean = 0.0; double sum = 0.0; double stdDev = 0.0; int count = 0; foreach (double val in values) { count++; double delta = val - mean; mean += delta / count; sum += delta * (val - mean); } if (1 < count) { stdDev = Math.Sqrt(sum / (count - 1)); } if (count > 0) { avgAndStdDev.Average = mean; avgAndStdDev.StdDev = stdDev; } return avgAndStdDev; } ////// Gets the average and standard deviation of a set in one pass /// /// The set to be operated on ///A StatTypes object with the Average and StdDev values /// for the set operated on public static StatTypes GetAvgAndStdDev(this IEnumerable<int> values) { StatTypes avgAndStdDev = new StatTypes(); // ref: http://warrenseen.com/blog/2006/03/13/how-to-calculate-standard-deviation/ double mean = 0.0; double sum = 0.0; double stdDev = 0.0; int count = 0; foreach (double val in values) { count++; double delta = val - mean; mean += delta / count; sum += delta * (val - mean); } if (1 < count) { stdDev = Math.Sqrt(sum / (count - 1)); } if (count > 0) { avgAndStdDev.Average = mean; avgAndStdDev.StdDev = stdDev; } return avgAndStdDev; } } }
Usage is made simple this way:
string metric = "DaysWorked"; StatTypes avgAndStdDev = (from row in table.AsEnumerable() where row.Field<double?>(metric) != null select row.Field<double>(metric)).GetAvgAndStdDev(); calculatedTarget["Mean"] = (object)avgAndStdDev.Average ?? DBNull.Value; calculatedTarget["StdDev"] = avgAndStdDev.StdDev;
As an aside, I had no idea how to name the class or namespace for any usefulness. However, I learned that I never use the class name, anyway, so perhaps it doesn't matter. *shrug*