Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make _power consider both sides #26

Merged
merged 1 commit into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/PowerAnalyses.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ using Distributions:
NoncentralT,
UnivariateDistribution,
cdf,
quantile
ccdf,
quantile,
cquantile
using Roots: find_zero

include("types.jl")
Expand Down
26 changes: 14 additions & 12 deletions src/power.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ Return `power` for which `quantile(d0, alpha) == quantile(d1, beta)` and `beta =
"""
function _power(d0::UnivariateDistribution, d1::UnivariateDistribution, alpha::Real, tail::Tail)
right_tail = tail == one_tail ? alpha : alpha / 2
except_right_tail = 1 - right_tail
critical_value = quantile(d0, except_right_tail)
beta = cdf(d1, critical_value)
return 1 - beta
upper_critical_value = cquantile(d0, right_tail)
if tail == one_tail
return ccdf(d1, upper_critical_value)
else
lower_critical_value = quantile(d0, right_tail)
return cdf(d1, lower_critical_value) + ccdf(d1, upper_critical_value)
end
end

"""
Expand All @@ -17,11 +20,9 @@ end
Return `alpha` for which `quantile(d0, alpha) == quantile(d1, beta)` and `beta = 1 - power`.
"""
function _alpha(d0::UnivariateDistribution, d1::UnivariateDistribution, power::Real, tail::Tail)
beta = 1 - power
critical_value = quantile(d1, beta)
except_right_tail = cdf(d0, critical_value)
right_tail = 1 - except_right_tail
return tail == one_tail ? right_tail : 2 * right_tail
return find_zero((0, 1)) do alpha
return _power(d0, d1, alpha, tail) - power
end
end

_distribution_parameters(T::IndependentSamplesTTest, n) = 2 * n - 2 # n1 + n2 - 2
Expand Down Expand Up @@ -122,9 +123,10 @@ end
Return the minimum effect size for some test `T` with significance level `alpha`, power `power` and sample size `n`.
"""
function get_es(T::StatisticalTest; alpha::Real, power::Real, n)
f(es) = get_alpha(T; es, power, n) - alpha
initial_value = (0, 10)
return find_zero(f, initial_value)
initial_value = (0, 1000)
return find_zero(initial_value) do es
get_power(T; es, alpha, n) - power
end
end

"""
Expand Down
15 changes: 8 additions & 7 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@ using Test: @testset, @test

@testset "IndependentSamplesTTest" begin
@testset "two_tails" begin
# This matches power.t.test(n=50, d=0.5, sig.level=NULL, power=0.95, type="two.sample", alternative="two.sided")
# but not pwr.t.test(n=50, d=0.5, sig.level=NULL, power=0.95, type="two.sample", alternative="two.sided")
# because the latter considers both sides of the distribution. A fix will probably require
# switching to root finding. The pwr.t.test matches # G*Power and is 0.3928954
@test get_alpha(IndependentSamplesTTest(two_tails); es, power, n) ≈ 0.3950408 rtol=1e-6
@test get_power(IndependentSamplesTTest(two_tails); es, alpha, n) ≈ 0.6968888 rtol=1e-6
# This matches pwr.t.test(n=50, d=0.5, sig.level=NULL, power=0.95, type="two.sample", alternative="two.sided")
# but not power.t.test(n=50, d=0.5, sig.level=NULL, power=0.95, type="two.sample", alternative="two.sided")
# because the latter considers both sides of the distribution. The pwr.t.test matches # G*Power and is 0.3928954
@test get_alpha(IndependentSamplesTTest(two_tails); es, power, n) ≈ 0.3928954 rtol=1e-6
@test get_power(IndependentSamplesTTest(two_tails); es, alpha, n) ≈ 0.6968934 rtol=1e-6
@test get_es(IndependentSamplesTTest(two_tails); alpha, power, n) ≈ 0.7281209 rtol=1e-4
@test get_n(IndependentSamplesTTest(two_tails); es, alpha, power) ≈ 104.928 rtol=1e-6
@test get_n(IndependentSamplesTTest(two_tails); es, alpha, power) ≈ 104.9279 rtol=1e-6

@test get_power(IndependentSamplesTTest(two_tails); es = 0.0, alpha, n) ≈ alpha
end
@testset "one_tail" begin
# R gives a warning that full precision might not have been achieved
Expand Down
Loading