1package stats 2 3import "math" 4 5// Quartiles holds the three quartile points 6type Quartiles struct { 7 Q1 float64 8 Q2 float64 9 Q3 float64 10} 11 12// Quartile returns the three quartile points from a slice of data 13func Quartile(input Float64Data) (Quartiles, error) { 14 15 il := input.Len() 16 if il == 0 { 17 return Quartiles{}, EmptyInputErr 18 } 19 20 // Start by sorting a copy of the slice 21 copy := sortedCopy(input) 22 23 // Find the cutoff places depeding on if 24 // the input slice length is even or odd 25 var c1 int 26 var c2 int 27 if il%2 == 0 { 28 c1 = il / 2 29 c2 = il / 2 30 } else { 31 c1 = (il - 1) / 2 32 c2 = c1 + 1 33 } 34 35 // Find the Medians with the cutoff points 36 Q1, _ := Median(copy[:c1]) 37 Q2, _ := Median(copy) 38 Q3, _ := Median(copy[c2:]) 39 40 return Quartiles{Q1, Q2, Q3}, nil 41 42} 43 44// InterQuartileRange finds the range between Q1 and Q3 45func InterQuartileRange(input Float64Data) (float64, error) { 46 if input.Len() == 0 { 47 return math.NaN(), EmptyInputErr 48 } 49 qs, _ := Quartile(input) 50 iqr := qs.Q3 - qs.Q1 51 return iqr, nil 52} 53 54// Midhinge finds the average of the first and third quartiles 55func Midhinge(input Float64Data) (float64, error) { 56 if input.Len() == 0 { 57 return math.NaN(), EmptyInputErr 58 } 59 qs, _ := Quartile(input) 60 mh := (qs.Q1 + qs.Q3) / 2 61 return mh, nil 62} 63 64// Trimean finds the average of the median and the midhinge 65func Trimean(input Float64Data) (float64, error) { 66 if input.Len() == 0 { 67 return math.NaN(), EmptyInputErr 68 } 69 70 c := sortedCopy(input) 71 q, _ := Quartile(c) 72 73 return (q.Q1 + (q.Q2 * 2) + q.Q3) / 4, nil 74} 75