Repository: JuliaStats/HypothesisTests.jl (julia)

Issue:
Lower and upper limits of CI for proportion
Should lower limit be `min(0, val)` and upper `max(val, 1)`?

for example:
```
confint(HypothesisTests.BinomialTest(0, 5), method = :agresti_coull)
```

Result
```
(**-**0.05457239484968546, 0.4890548596328611)
```

Pull request description:
closes #295

Patch:
diff --git a/Project.toml b/Project.toml
index 768b4912..e707ba77 100644
--- a/Project.toml
+++ b/Project.toml
@@ -1,6 +1,6 @@
 name = "HypothesisTests"
 uuid = "09f84164-cd44-5f33-b23f-e6b0d136a0d5"
-version = "0.10.12"
+version = "0.10.13"
 
 [deps]
 Combinatorics = "861a8166-3701-5b0c-9a16-15d98fcdc6aa"
diff --git a/src/binomial.jl b/src/binomial.jl
index 55fcbbfa..d2aa74f4 100644
--- a/src/binomial.jl
+++ b/src/binomial.jl
@@ -140,7 +140,9 @@ end
 function ci_wald(x::BinomialTest, alpha::Float64=0.05)
     μ = x.x / x.n
     σ = sqrt(μ*(1-μ)/x.n)
-    (quantile(Normal(μ, σ), alpha/2), quantile(Normal(μ, σ), 1-alpha/2))
+    lower, upper = (quantile(Normal(μ, σ), alpha/2), quantile(Normal(μ, σ), 1-alpha/2))
+    # make sure we stay in [0, 1]
+    (max(lower, 0), min(upper, 1))
 end
 
 # Jeffreys interval
@@ -154,7 +156,8 @@ function ci_agresti_coull(x::BinomialTest, alpha::Float64=0.05)
     n = x.n + q^2
     μ = (x.x + q^2/2)/n
     σ = sqrt(μ*(1-μ)/n)
-    (μ-q*σ, μ+q*σ)
+    # make sure we stay in [0, 1]
+    (max(μ-q*σ, 0), min(μ+q*σ, 1))
 end
 
 # Wilson score interval
@@ -166,7 +169,8 @@ function ci_wilson(x::BinomialTest, alpha::Float64=0.05)
     μ /= denominator
     σ = sqrt(p*(1-p)/x.n + q^2/(4x.n^2))
     σ /= denominator
-    (μ-q*σ, μ+q*σ)
+    # make sure we stay in [0, 1]
+    (max(μ-q*σ, 0), min(μ+q*σ, 1))
 end
 
 # Arcsine transformation interval as based on Cohen's H: https://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval#Arcsine_transformation


Test patch:
diff --git a/test/binomial.jl b/test/binomial.jl
index b0f5197d..622b168b 100644
--- a/test/binomial.jl
+++ b/test/binomial.jl
@@ -59,6 +59,20 @@ using HypothesisTests: default_tail
     t = BinomialTest(100, 100, 0.99)
     @test pvalue(t) ≈ 0.7320646825464584
     show(IOBuffer(), t)
+
+    # from issue #295
+    # without clamping: (-0.05457239484968546, 0.4890548596328611)
+    @test_ci_approx confint(BinomialTest(0, 5), method=:agresti_coull) (0.0, 0.4890548596328611)
+    # without clamping: (0.5109451403671388, 1.0545723948496855)
+    @test_ci_approx confint(BinomialTest(5, 5), method=:agresti_coull) (0.5109451403671388, 1.0)
+    # without clamping: (-0.15060901623063327, 0.5506090162306333)
+    @test_ci_approx confint(BinomialTest(1, 5), method=:wald) (0.0, 0.5506090162306333)
+    # without clamping: (0.44939098376936687, 1.1506090162306333)
+    @test_ci_approx confint(BinomialTest(4, 5), method=:wald) (0.44939098376936687, 1.0)
+    # without clamping: (-2.7755575615628914e-17, 0.2775327998628899)
+    @test_ci_approx confint(BinomialTest(0, 10), method=:wilson) (0.0, 0.2775327998628899)
+    # without clamping: (0.7575059933447587, 1.0000000000000002)
+    @test_ci_approx confint(BinomialTest(12, 12), method=:wilson) (0.7575059933447587, 1.0)
 end
 
 @testset "SignTest" begin