Skip to content

Commit

Permalink
More informative error messages (#698)
Browse files Browse the repository at this point in the history
* informative error message when passed type instead
of instance

* more informative error for R2

* NEWS

* JuliaFormatter
  • Loading branch information
palday committed Aug 9, 2023
1 parent 2af0322 commit c99a2d3
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 0 deletions.
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
* New kwarg `amalgamate` can be used to disable amalgation of random0effects terms sharing a single grouping variable. Generally, `amalgamate=false` will result in a slower fit, but may improve convergence in some pathological cases. Note that this feature is experimental and changes to it are **not** considered breakin. [#673]
* More informative error messages when passing a `Distribution` or `Link` type instead of the desired instance. [#698]
* More informative error message on the intentional decision not to define methods for the coefficient of determination. [#698]

MixedModels v4.16.0 Release Notes
==============================
Expand Down Expand Up @@ -449,4 +451,5 @@ Package dependencies
[#681]: https://github.com/JuliaStats/MixedModels.jl/issues/681
[#682]: https://github.com/JuliaStats/MixedModels.jl/issues/682
[#694]: https://github.com/JuliaStats/MixedModels.jl/issues/694
[#698]: https://github.com/JuliaStats/MixedModels.jl/issues/698
[#703]: https://github.com/JuliaStats/MixedModels.jl/issues/703
20 changes: 20 additions & 0 deletions src/generalizedlinearmixedmodel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,26 @@ end

StatsAPI.fitted(m::GeneralizedLinearMixedModel) = m.resp.mu

function GeneralizedLinearMixedModel(
f::FormulaTerm,
tbl,
d::Type,
args...;
kwargs...,
)
throw(ArgumentError("Expected a Distribution instance (`$d()`), got a type (`$d`)."))
end

function GeneralizedLinearMixedModel(
f::FormulaTerm,
tbl,
d::Distribution,
l::Type;
kwargs...
)
throw(ArgumentError("Expected a Link instance (`$l()`), got a type (`$l`)."))
end

function GeneralizedLinearMixedModel(
f::FormulaTerm,
tbl,
Expand Down
40 changes: 40 additions & 0 deletions src/mixedmodel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,28 @@ issingular(m::GeneralizedLinearMixedModel, θ=m.optsum.final) = any(lowerbd(m) .
# FIXME: better to base this on m.optsum.returnvalue
StatsAPI.isfitted(m::MixedModel) = m.optsum.feval > 0

function StatsAPI.fit(
::Type{<:MixedModel},
f::FormulaTerm,
tbl,
d::Type,
args...;
kwargs...
)
throw(ArgumentError("Expected a Distribution instance (`$d()`), got a type (`$d`)."))
end

function StatsAPI.fit(
::Type{<:MixedModel},
f::FormulaTerm,
tbl,
d::Distribution,
l::Type;
kwargs...
)
throw(ArgumentError("Expected a Link instance (`$l()`), got a type (`$l`)."))
end

StatsAPI.meanresponse(m::MixedModel) = mean(m.y)

"""
Expand All @@ -97,6 +119,24 @@ function retbl(mat, trm)
)
end

StatsAPI.adjr2(m::MixedModel) = r2(m)

function StatsAPI.r2(m::MixedModel)
@error (
"""There is no uniquely defined coefficient of determination for mixed models
that has all the properties of the corresponding value for classical
linear models. The GLMM FAQ provides more detail:
https://bbolker.github.io/mixedmodels-misc/glmmFAQ.html#how-do-i-compute-a-coefficient-of-determination-r2-or-an-analogue-for-glmms
Alternatively, MixedModelsExtras provides a naive implementation, but
the warnings there and in the FAQ should be taken seriously!
"""
)
throw(MethodError(r2, (m,)))
end

"""
raneftables(m::MixedModel; uscale = false)
Expand Down
14 changes: 14 additions & 0 deletions test/pirls.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ include("modelcache.jl")
@test MixedModel(f, d, Bernoulli(), ProbitLink()) isa GeneralizedLinearMixedModel
end

@testset "Type for instance" begin
vaform = @formula(r2 ~ 1 + anger + gender + btype + situ + (1|subj) + (1|item))
verbagg = dataset(:verbagg)
@test_throws ArgumentError fit(MixedModel, vaform, verbagg, Bernoulli, LogitLink)
@test_throws ArgumentError fit(MixedModel, vaform, verbagg, Bernoulli(), LogitLink)
@test_throws ArgumentError fit(MixedModel, vaform, verbagg, Bernoulli, LogitLink())
@test_throws ArgumentError fit(GeneralizedLinearMixedModel, vaform, verbagg, Bernoulli, LogitLink)
@test_throws ArgumentError fit(GeneralizedLinearMixedModel, vaform, verbagg, Bernoulli(), LogitLink)
@test_throws ArgumentError fit(GeneralizedLinearMixedModel, vaform, verbagg, Bernoulli, LogitLink())
@test_throws ArgumentError GeneralizedLinearMixedModel(vaform, verbagg, Bernoulli, LogitLink)
@test_throws ArgumentError GeneralizedLinearMixedModel(vaform, verbagg, Bernoulli(), LogitLink)
@test_throws ArgumentError GeneralizedLinearMixedModel(vaform, verbagg, Bernoulli, LogitLink())
end

@testset "contra" begin
contra = dataset(:contra)
thin = 5
Expand Down
15 changes: 15 additions & 0 deletions test/pls.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using GLM # bring r2 into scope
using LinearAlgebra
using MixedModels
using PooledArrays
Expand Down Expand Up @@ -688,3 +689,17 @@ end
# but this is surprisingly hard to trigger in a reliable way across platforms
# just because of the vagaries of floating point.
end

@testset "methods we don't define" begin
m = first(models(:sleepstudy))
for f in [r2, adjr2]
@test_logs (:error,) begin
try
f(m)
catch
# capture the error, do nothing
end
end
@test_throws MethodError @suppress f(m)
end
end

0 comments on commit c99a2d3

Please sign in to comment.