Add math.nearestrank() SQL function

This commit is contained in:
Tobie Morgan Hitchcock 2018-04-29 14:02:58 +01:00
parent 2878b29dde
commit 86b81c469e
4 changed files with 29 additions and 6 deletions

View file

@ -56,6 +56,7 @@ var aggrs = map[string]bool{
"math.midhinge": true,
"math.min": true,
"math.mode": true,
"math.nearestrank": true,
"math.percentile": true,
"math.sample": true,
"math.spread": true,
@ -139,6 +140,7 @@ var funcs = map[string]map[int]interface{}{
"math.midhinge": {1: nil},
"math.min": {1: nil},
"math.mode": {1: nil},
"math.nearestrank": {2: nil},
"math.percentile": {2: nil},
"math.round": {1: nil},
"math.sample": {2: nil},

View file

@ -146,6 +146,8 @@ func Run(ctx context.Context, name string, args ...interface{}) (interface{}, er
return mathMin(ctx, args...)
case "math.mode":
return mathMode(ctx, args...)
case "math.nearestrank":
return mathNearestRank(ctx, args...)
case "math.percentile":
return mathPercentile(ctx, args...)
case "math.round":

View file

@ -115,6 +115,14 @@ func mathMode(ctx context.Context, args ...interface{}) (out []float64, err erro
return math.Mode(vals), nil
}
func mathNearestRank(ctx context.Context, args ...interface{}) (out interface{}, err error) {
vals := ensureFloats(args[0])
if perc, ok := ensureFloat(args[1]); ok {
return outputFloat(math.NearestRankPercentile(vals, perc))
}
return
}
func mathPercentile(ctx context.Context, args ...interface{}) (out interface{}, err error) {
vals := ensureFloats(args[0])
if perc, ok := ensureFloat(args[1]); ok {
@ -152,7 +160,7 @@ func mathSqrt(ctx context.Context, args ...interface{}) (out interface{}, err er
func mathStddev(ctx context.Context, args ...interface{}) (out interface{}, err error) {
vals := ensureFloats(args[0])
return outputFloat(math.PopulationStandardDeviation(vals))
return outputFloat(math.SampleStandardDeviation(vals))
}
func mathSum(ctx context.Context, args ...interface{}) (out interface{}, err error) {
@ -175,5 +183,5 @@ func mathTrimean(ctx context.Context, args ...interface{}) (out interface{}, err
func mathVariance(ctx context.Context, args ...interface{}) (out interface{}, err error) {
vals := ensureFloats(args[0])
return outputFloat(math.PopulationVariance(vals))
return outputFloat(math.SampleVariance(vals))
}

View file

@ -179,6 +179,17 @@ func TestMath(t *testing.T) {
So(res, ShouldResemble, []float64{1})
})
Convey("math.nearestrank() works properly", t, func() {
res, _ = Run(context.Background(), "math.nearestrank", "test", 90)
So(res, ShouldEqual, nil)
res, _ = Run(context.Background(), "math.nearestrank", 10, "oops")
So(res, ShouldEqual, nil)
res, _ = Run(context.Background(), "math.nearestrank", 10, 90)
So(res, ShouldEqual, 10)
res, _ = Run(context.Background(), "math.nearestrank", test, 90)
So(res, ShouldEqual, 4.5)
})
Convey("math.percentile() works properly", t, func() {
res, _ = Run(context.Background(), "math.percentile", "test", 90)
So(res, ShouldEqual, nil)
@ -232,9 +243,9 @@ func TestMath(t *testing.T) {
res, _ = Run(context.Background(), "math.stddev", "test")
So(res, ShouldEqual, nil)
res, _ = Run(context.Background(), "math.stddev", 10)
So(res, ShouldEqual, 0)
So(res, ShouldEqual, nil)
res, _ = Run(context.Background(), "math.stddev", test)
So(res, ShouldEqual, 1.2747548783981961)
So(res, ShouldEqual, 1.4719601443879744)
})
Convey("math.sum() works properly", t, func() {
@ -274,9 +285,9 @@ func TestMath(t *testing.T) {
res, _ = Run(context.Background(), "math.variance", "test")
So(res, ShouldEqual, nil)
res, _ = Run(context.Background(), "math.variance", 10)
So(res, ShouldEqual, 0)
So(res, ShouldEqual, nil)
res, _ = Run(context.Background(), "math.variance", test)
So(res, ShouldEqual, 1.625)
So(res, ShouldEqual, 2.1666666666666665)
})
}