Share via


VB.NET: Statistical Numeric Collection Extension Functions


Overview

In many real world scenarios you work with large collections of numbers. VB.Net has several functions for analyzing these collections, such as Sum, Count, Average, Min, Max. This example adds several more functions:

  • Median: This is the midpoint number in the ASC sorted collection
  • **Mode: **This is the most frequent number(s) in the collection
  • **Range: **The difference between Max and Min
  • IQR:** **The difference between the third Quartile (Q3) and the first Quartile (Q1)
  • **Q1: **The Median of the first half of the sorted collection
  • Q3: ** **The Median of the second half of the sorted collection
  • StdDev: A measure of how spread the numbers are.

 

These are overloaded for use with collections of all standard numeric datatypes.


An Example of the Overloaded Functions



      #Region "     Byte"  
   
                    <Extension>      
                    Public Function  Median(l As  IEnumerable(Of Byte)) As  Decimal  
                        l = l.OrderBy(      Function      (b) b)      
                        If l.Count Mod 2 = 1 Then 'odd count  
                            Return CDec(l(CInt(Math.Floor(l.Count / 2))))  
                        Else 'even count  
                            Return CDec((l(l.Count \ 2 - 1) + l(l.Count \ 2)) / 2)  
                        End If  
                    End Function  
   
                    <Extension>      
                    Public Function  Mode(l As  IEnumerable(Of Byte)) As  String  
                        Dim occurrences As New  Dictionary(Of Byte, Integer)  
   
                        For x As Integer  = 0 To  l.Count - 1  
                            If occurrences.ContainsKey(l(x)) Then  
                                occurrences(l(x)) += 1      
                            Else      
                                occurrences.Add(l(x), 1)      
                            End If  
                        Next      
   
                        Return String.Join(", ", occurrences.Where(Function(kvp1) kvp1.Value = occurrences.Max(Function(kvp2) kvp2.Value)).Select(Function(kvp3) kvp3.Key.ToString).ToArray)  
                    End Function  
   
                    <Extension>      
                    Public Function  Range(l As  IEnumerable(Of Byte)) As  Byte  
                        Return l.Max - l.Min  
                    End Function  
   
                    <Extension>      
                    Public Function  IQR(l As  IEnumerable(Of Byte)) As  Decimal  
                        Return Q3(l) - Q1(l)  
                    End Function  
   
                    <Extension>      
                    Public Function  Q1(l As  IEnumerable(Of Byte)) As  Decimal  
                        Return quartiles(l)  
                    End Function  
   
                    <Extension>      
                    Public Function  Q3(l As  IEnumerable(Of Byte)) As  Decimal  
                        Return quartiles(l, False)  
                    End Function  
   
                    Private Function  quartiles(l As  IEnumerable(Of Byte), Optional  Q1 As  Boolean = True) As  Decimal  
                        Dim count As Integer  = l.Count  
                        l = l.OrderBy(      Function      (x) x)      
   
                        Dim firstHalf As New  List(Of Decimal)  
                        Dim secondHalf As New  List(Of Decimal)  
   
                        Dim half As Integer  
   
                        If count Mod 2 = 1 Then 'odd count  
                            half =       CInt      (Math.Floor(count / 2))      
                        Else 'even count  
                            half = count \ 2      
                        End If  
   
                        firstHalf.AddRange(Array.ConvertAll(l.Cast(Of       Byte      ).Take(half).ToArray,       Function      (b)       CDec      (b)))      
                        secondHalf.AddRange(Array.ConvertAll(l.Cast(Of       Byte      ).Skip(count - half).ToArray,       Function      (b)       CDec      (b)))      
   
                        Return If(Q1, Median(firstHalf), Median(secondHalf))  
   
                    End Function  
   
                    <Extension>      
                    Public Function  StdDev(l As  IEnumerable(Of Byte), Optional  population As  Boolean = True) As  Decimal  
                        Dim mean As Decimal  = l.Average(Function(x) CDec(x))  
   
                        Dim squaredDifference() As Decimal  = Array.ConvertAll(l.ToArray, Function(x As  Byte) CDec((x - mean) ^ 2))  
   
                        Return If(population, CDec(Math.Sqrt(squaredDifference.Average)), CDec(Math.Sqrt(minusOneAverage(squaredDifference))))  
                    End Function  
   
      #End Region  

Downloads