You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
1.5 KiB
74 lines
1.5 KiB
package stats |
|
|
|
import "math" |
|
|
|
// Quartiles holds the three quartile points |
|
type Quartiles struct { |
|
Q1 float64 |
|
Q2 float64 |
|
Q3 float64 |
|
} |
|
|
|
// Quartile returns the three quartile points from a slice of data |
|
func Quartile(input Float64Data) (Quartiles, error) { |
|
|
|
il := input.Len() |
|
if il == 0 { |
|
return Quartiles{}, EmptyInput |
|
} |
|
|
|
// Start by sorting a copy of the slice |
|
copy := sortedCopy(input) |
|
|
|
// Find the cutoff places depeding on if |
|
// the input slice length is even or odd |
|
var c1 int |
|
var c2 int |
|
if il%2 == 0 { |
|
c1 = il / 2 |
|
c2 = il / 2 |
|
} else { |
|
c1 = (il - 1) / 2 |
|
c2 = c1 + 1 |
|
} |
|
|
|
// Find the Medians with the cutoff points |
|
Q1, _ := Median(copy[:c1]) |
|
Q2, _ := Median(copy) |
|
Q3, _ := Median(copy[c2:]) |
|
|
|
return Quartiles{Q1, Q2, Q3}, nil |
|
|
|
} |
|
|
|
// InterQuartileRange finds the range between Q1 and Q3 |
|
func InterQuartileRange(input Float64Data) (float64, error) { |
|
if input.Len() == 0 { |
|
return math.NaN(), EmptyInput |
|
} |
|
qs, _ := Quartile(input) |
|
iqr := qs.Q3 - qs.Q1 |
|
return iqr, nil |
|
} |
|
|
|
// Midhinge finds the average of the first and third quartiles |
|
func Midhinge(input Float64Data) (float64, error) { |
|
if input.Len() == 0 { |
|
return math.NaN(), EmptyInput |
|
} |
|
qs, _ := Quartile(input) |
|
mh := (qs.Q1 + qs.Q3) / 2 |
|
return mh, nil |
|
} |
|
|
|
// Trimean finds the average of the median and the midhinge |
|
func Trimean(input Float64Data) (float64, error) { |
|
if input.Len() == 0 { |
|
return math.NaN(), EmptyInput |
|
} |
|
|
|
c := sortedCopy(input) |
|
q, _ := Quartile(c) |
|
|
|
return (q.Q1 + (q.Q2 * 2) + q.Q3) / 4, nil |
|
}
|
|
|