Skip to content

Commit 872bba1

Browse files
dmbatespalday
andauthored
Improve test coverage for utilities (#304)
* Spelling * Add allequal methods, increase test coverage * Update test/likelihoodratiotest.jl Co-Authored-By: Phillip Alday <[email protected]> Co-authored-by: Phillip Alday <[email protected]>
1 parent 26fafe2 commit 872bba1

File tree

5 files changed

+60
-24
lines changed

5 files changed

+60
-24
lines changed

src/likelihoodratiotest.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Note that nesting of the models is not checked. It is incumbent on the user to
5353
"""
5454
function likelihoodratiotest(m::LinearMixedModel...)
5555
allequal(getproperty.(getproperty.(m,:optsum),:REML)) ||
56-
throw(ArgumentError("Models must all be fit with the same objective (i.e. alll ML or all REML)"))
56+
throw(ArgumentError("Models must all be fit with the same objective (i.e. all ML or all REML)"))
5757
if any(getproperty.(getproperty.(m,:optsum),:REML))
5858
allequal(coefnames.(m)) ||
5959
throw(ArgumentError("Likelihood-ratio tests for REML-fitted models are only valid when the fixed-effects specifications are identical"))

src/utilities.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ function allequal(x::Array; comparison=isequal)::Bool
77
all(comparison.(first(x), x))
88
end
99

10+
allequal(x::Vector{Bool})::Bool = !any(x) || all(x)
11+
12+
allequal(x::NTuple{N,Bool}) where {N} = !any(x) || all(x)
13+
1014
function allequal(x::Tuple; comparison=isequal)::Bool
1115
all(comparison.(first(x), x))
1216
end
@@ -50,7 +54,7 @@ end
5054
densify(A::AbstractMatrix, threshold::Real = 0.3) = A
5155

5256
densify(A::SparseVector, threshold::Real = 0.3) = Vector(A)
53-
densify(A::Diagonal{T,SparseVector}, threshold::Real = 0.3) where {T} =
57+
densify(A::Diagonal{T,SparseVector{T,Ti}}, threshold::Real = 0.3) where {T,Ti} =
5458
Diagonal(Vector(A.diag))
5559

5660
"""

test/likelihoodratiotest.jl

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,50 @@
1-
using MixedModels, Test
2-
import GLM: ProbitLink
1+
using MixedModels
2+
using Test
3+
4+
using MixedModels: dataset, likelihoodratiotest
5+
using GLM: ProbitLink
36

47
@testset "likelihoodratio test" begin
5-
slp = MixedModels.dataset(:sleepstudy);
8+
slp = dataset(:sleepstudy);
69
fm0 = fit(MixedModel,@formula(reaction ~ 1 + (1+days|subj)),slp);
710
fm1 = fit(MixedModel,@formula(reaction ~ 1 + days + (1+days|subj)),slp);
8-
lrt = MixedModels.likelihoodratiotest(fm0,fm1);
11+
lrt = likelihoodratiotest(fm0,fm1);
912

1013
@test [deviance(fm0), deviance(fm1)] == lrt.deviance
11-
@test deviance(fm0) - deviance(fm1) == first(lrt.tests.deviancediff)
12-
@test first(lrt.tests.dofdiff) == 1
14+
@test deviance(fm0) - deviance(fm1) == only(lrt.tests.deviancediff)
15+
@test only(lrt.tests.dofdiff) == 1
1316
@test sum(map(length,lrt.tests)) == 3
1417
@test sum(map(length,lrt.pvalues)) == 1
1518
@test sum(map(length,lrt.models)) == 4
1619
@test length(lrt.formulae) == 2
1720
show(IOBuffer(),lrt);
21+
@test :pvalues in propertynames(lrt)
1822

1923

2024
# mix of REML and ML
2125
fm0 = fit(MixedModel,@formula(reaction ~ 1 + (1+days|subj)),slp, REML=true);
22-
@test_throws ArgumentError MixedModels.likelihoodratiotest(fm0,fm1)
26+
@test_throws ArgumentError likelihoodratiotest(fm0,fm1)
2327

2428
# differing FE with REML
2529
fm1 = fit(MixedModel,@formula(reaction ~ 1 + days + (1+days|subj)),slp, REML=true);
26-
fm10 = fit(MixedModel,@formula(reaction ~ 1 + days + (1|subj)),slp, REML=true);
27-
@test_throws ArgumentError MixedModels.likelihoodratiotest(fm0,fm1);
30+
31+
@test_throws ArgumentError likelihoodratiotest(fm0,fm1)
2832

2933
contra = MixedModels.dataset(:contra);
3034
gm0 = fit(MixedModel, @formula(use ~ 1+age+urban+livch+(1|urbdist)), contra, Bernoulli(), fast=true);
3135
gm1 = fit(MixedModel, @formula(use ~ 1+age+abs2(age)+urban+livch+(1|urbdist)), contra, Bernoulli(), fast=true);
32-
lrt = MixedModels.likelihoodratiotest(gm0,gm1);
36+
lrt = likelihoodratiotest(gm0,gm1);
3337
@test [deviance(gm0), deviance(gm1)] == lrt.deviance
34-
@test deviance(gm0) - deviance(gm1) == first(lrt.tests.deviancediff)
38+
@test deviance(gm0) - deviance(gm1) == only(lrt.tests.deviancediff)
3539
@test first(lrt.tests.dofdiff) == 1
36-
@test sum(map(length,lrt.tests)) == 3
37-
@test sum(map(length,lrt.pvalues)) == 1
38-
@test sum(map(length,lrt.models)) == 4
40+
@test sum(length, lrt.tests) == 3
41+
@test sum(length, lrt.pvalues) == 1
42+
@test sum(length, lrt.models) == 4
3943
@test length(lrt.formulae) == 2
4044

4145
# mismatched links
4246
gm_probit = fit(MixedModel, @formula(use ~ 1+age+urban+livch+(1|urbdist)), contra, Bernoulli(), ProbitLink(), fast=true);
43-
@test_throws ArgumentError MixedModels.likelihoodratiotest(gm0,gm_probit)
47+
@test_throws ArgumentError likelihoodratiotest(gm0,gm_probit)
4448

4549
# mismatched families
4650
gm_poisson = fit(MixedModel, @formula(use ~ 1+age+urban+livch+(1|urbdist)), contra, Poisson(), fast=true);

test/pls.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,14 @@ end
242242

243243
@testset "PCA" begin
244244
@test length(fm1.rePCA) == 3
245-
@test length(MixedModels.PCA(fm1)) == 3
245+
pca = MixedModels.PCA(fm1)
246+
@test length(pca) == 3
247+
@test :covcor in propertynames(first(pca))
248+
str = String(take!(io))
249+
show(io, first(pca), stddevs=true, variances=true)
250+
str = String(take!(io))
251+
@test !isempty(findall("Standard deviations:", str))
252+
@test !isempty(findall("Variances:", str))
246253
end
247254

248255
show(io, BlockDescription(fm1))

test/utilities.jl

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,32 @@
1-
using LinearAlgebra, MixedModels, Random, SparseArrays, Test
1+
using LinearAlgebra
2+
using MixedModels
3+
using Random
4+
using SparseArrays
5+
using Test
26

3-
@testset "utilities" begin
4-
@test MixedModels.average(1.1, 1.2) == 1.15
5-
@test MixedModels.densify(sparse(1:5, 1:5, ones(5))) == Diagonal(ones(5))
7+
using MixedModels: allequal, average, densify, dataset
8+
9+
@testset "average" begin
10+
@test average(1.1, 1.2) == 1.15
11+
end
12+
13+
@testset "densify" begin
14+
@test densify(sparse(1:5, 1:5, ones(5))) == Diagonal(ones(5))
615
rsparsev = SparseVector(float.(rand(MersenneTwister(123454321), Bool, 20)))
7-
@test MixedModels.densify(rsparsev) == Vector(rsparsev)
8-
@test MixedModels.densify(Diagonal(rsparsev)) == Diagonal(Vector(rsparsev))
16+
@test densify(rsparsev) == Vector(rsparsev)
17+
@test densify(Diagonal(rsparsev)) == Diagonal(Vector(rsparsev))
18+
end
19+
20+
@testset "allequal" begin
21+
@test allequal((true, true, true))
22+
@test allequal([true, true, true])
23+
@test !allequal((true, false, true))
24+
@test !allequal([true, false, true])
25+
@test !allequal(collect(1:4))
26+
@test allequal((false, false, false))
27+
@test allequal([false, false, false])
28+
@test allequal(ones(3))
29+
@test allequal(1, 1, 1)
930
end
1031

1132
@testset "threaded_replicate" begin

0 commit comments

Comments
 (0)