Skip to content

Commit

Permalink
Improve test coverage for utilities (#304)
Browse files Browse the repository at this point in the history
* 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]>
  • Loading branch information
dmbates and palday authored Apr 14, 2020
1 parent 26fafe2 commit 872bba1
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 24 deletions.
2 changes: 1 addition & 1 deletion src/likelihoodratiotest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ Note that nesting of the models is not checked. It is incumbent on the user to
"""
function likelihoodratiotest(m::LinearMixedModel...)
allequal(getproperty.(getproperty.(m,:optsum),:REML)) ||
throw(ArgumentError("Models must all be fit with the same objective (i.e. alll ML or all REML)"))
throw(ArgumentError("Models must all be fit with the same objective (i.e. all ML or all REML)"))
if any(getproperty.(getproperty.(m,:optsum),:REML))
allequal(coefnames.(m)) ||
throw(ArgumentError("Likelihood-ratio tests for REML-fitted models are only valid when the fixed-effects specifications are identical"))
Expand Down
6 changes: 5 additions & 1 deletion src/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ function allequal(x::Array; comparison=isequal)::Bool
all(comparison.(first(x), x))
end

allequal(x::Vector{Bool})::Bool = !any(x) || all(x)

allequal(x::NTuple{N,Bool}) where {N} = !any(x) || all(x)

function allequal(x::Tuple; comparison=isequal)::Bool
all(comparison.(first(x), x))
end
Expand Down Expand Up @@ -50,7 +54,7 @@ end
densify(A::AbstractMatrix, threshold::Real = 0.3) = A

densify(A::SparseVector, threshold::Real = 0.3) = Vector(A)
densify(A::Diagonal{T,SparseVector}, threshold::Real = 0.3) where {T} =
densify(A::Diagonal{T,SparseVector{T,Ti}}, threshold::Real = 0.3) where {T,Ti} =
Diagonal(Vector(A.diag))

"""
Expand Down
34 changes: 19 additions & 15 deletions test/likelihoodratiotest.jl
Original file line number Diff line number Diff line change
@@ -1,46 +1,50 @@
using MixedModels, Test
import GLM: ProbitLink
using MixedModels
using Test

using MixedModels: dataset, likelihoodratiotest
using GLM: ProbitLink

@testset "likelihoodratio test" begin
slp = MixedModels.dataset(:sleepstudy);
slp = dataset(:sleepstudy);
fm0 = fit(MixedModel,@formula(reaction ~ 1 + (1+days|subj)),slp);
fm1 = fit(MixedModel,@formula(reaction ~ 1 + days + (1+days|subj)),slp);
lrt = MixedModels.likelihoodratiotest(fm0,fm1);
lrt = likelihoodratiotest(fm0,fm1);

@test [deviance(fm0), deviance(fm1)] == lrt.deviance
@test deviance(fm0) - deviance(fm1) == first(lrt.tests.deviancediff)
@test first(lrt.tests.dofdiff) == 1
@test deviance(fm0) - deviance(fm1) == only(lrt.tests.deviancediff)
@test only(lrt.tests.dofdiff) == 1
@test sum(map(length,lrt.tests)) == 3
@test sum(map(length,lrt.pvalues)) == 1
@test sum(map(length,lrt.models)) == 4
@test length(lrt.formulae) == 2
show(IOBuffer(),lrt);
@test :pvalues in propertynames(lrt)


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

# differing FE with REML
fm1 = fit(MixedModel,@formula(reaction ~ 1 + days + (1+days|subj)),slp, REML=true);
fm10 = fit(MixedModel,@formula(reaction ~ 1 + days + (1|subj)),slp, REML=true);
@test_throws ArgumentError MixedModels.likelihoodratiotest(fm0,fm1);

@test_throws ArgumentError likelihoodratiotest(fm0,fm1)

contra = MixedModels.dataset(:contra);
gm0 = fit(MixedModel, @formula(use ~ 1+age+urban+livch+(1|urbdist)), contra, Bernoulli(), fast=true);
gm1 = fit(MixedModel, @formula(use ~ 1+age+abs2(age)+urban+livch+(1|urbdist)), contra, Bernoulli(), fast=true);
lrt = MixedModels.likelihoodratiotest(gm0,gm1);
lrt = likelihoodratiotest(gm0,gm1);
@test [deviance(gm0), deviance(gm1)] == lrt.deviance
@test deviance(gm0) - deviance(gm1) == first(lrt.tests.deviancediff)
@test deviance(gm0) - deviance(gm1) == only(lrt.tests.deviancediff)
@test first(lrt.tests.dofdiff) == 1
@test sum(map(length,lrt.tests)) == 3
@test sum(map(length,lrt.pvalues)) == 1
@test sum(map(length,lrt.models)) == 4
@test sum(length, lrt.tests) == 3
@test sum(length, lrt.pvalues) == 1
@test sum(length, lrt.models) == 4
@test length(lrt.formulae) == 2

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

# mismatched families
gm_poisson = fit(MixedModel, @formula(use ~ 1+age+urban+livch+(1|urbdist)), contra, Poisson(), fast=true);
Expand Down
9 changes: 8 additions & 1 deletion test/pls.jl
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,14 @@ end

@testset "PCA" begin
@test length(fm1.rePCA) == 3
@test length(MixedModels.PCA(fm1)) == 3
pca = MixedModels.PCA(fm1)
@test length(pca) == 3
@test :covcor in propertynames(first(pca))
str = String(take!(io))
show(io, first(pca), stddevs=true, variances=true)
str = String(take!(io))
@test !isempty(findall("Standard deviations:", str))
@test !isempty(findall("Variances:", str))
end

show(io, BlockDescription(fm1))
Expand Down
33 changes: 27 additions & 6 deletions test/utilities.jl
Original file line number Diff line number Diff line change
@@ -1,11 +1,32 @@
using LinearAlgebra, MixedModels, Random, SparseArrays, Test
using LinearAlgebra
using MixedModels
using Random
using SparseArrays
using Test

@testset "utilities" begin
@test MixedModels.average(1.1, 1.2) == 1.15
@test MixedModels.densify(sparse(1:5, 1:5, ones(5))) == Diagonal(ones(5))
using MixedModels: allequal, average, densify, dataset

@testset "average" begin
@test average(1.1, 1.2) == 1.15
end

@testset "densify" begin
@test densify(sparse(1:5, 1:5, ones(5))) == Diagonal(ones(5))
rsparsev = SparseVector(float.(rand(MersenneTwister(123454321), Bool, 20)))
@test MixedModels.densify(rsparsev) == Vector(rsparsev)
@test MixedModels.densify(Diagonal(rsparsev)) == Diagonal(Vector(rsparsev))
@test densify(rsparsev) == Vector(rsparsev)
@test densify(Diagonal(rsparsev)) == Diagonal(Vector(rsparsev))
end

@testset "allequal" begin
@test allequal((true, true, true))
@test allequal([true, true, true])
@test !allequal((true, false, true))
@test !allequal([true, false, true])
@test !allequal(collect(1:4))
@test allequal((false, false, false))
@test allequal([false, false, false])
@test allequal(ones(3))
@test allequal(1, 1, 1)
end

@testset "threaded_replicate" begin
Expand Down

0 comments on commit 872bba1

Please sign in to comment.