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