From 1433b1e1ffa7614bc55b1bad5c1a28b035375fb6 Mon Sep 17 00:00:00 2001 From: Phillip Alday Date: Sat, 19 Aug 2023 17:27:12 -0500 Subject: [PATCH] YAS --- .github/workflows/YASG.yml | 1 + ext/EffectsGLMExt.jl | 8 ++++---- ext/EffectsMixedModelsExt.jl | 6 +++--- format/run.jl | 2 +- src/regressionmodel.jl | 15 +++++++-------- test/delta_method.jl | 27 ++++++++++++++------------- 6 files changed, 30 insertions(+), 29 deletions(-) diff --git a/.github/workflows/YASG.yml b/.github/workflows/YASG.yml index 4896c32..5aee7b9 100644 --- a/.github/workflows/YASG.yml +++ b/.github/workflows/YASG.yml @@ -11,6 +11,7 @@ on: - 'src/**' - 'test/**' - 'docs/**' + - 'ext/**' - '.github/workflows/YASG.yml' - 'format/**' jobs: diff --git a/ext/EffectsGLMExt.jl b/ext/EffectsGLMExt.jl index e76bcfb..52bc63b 100644 --- a/ext/EffectsGLMExt.jl +++ b/ext/EffectsGLMExt.jl @@ -12,9 +12,10 @@ using StatsModels: TableRegressionModel _link(m::TableRegressionModel{<:AbstractGLM}) = Link(m.model) _link(m::AbstractGLM) = Link(m) -function Effects._difference_method!(eff::Vector{T}, err::Vector{T}, - model::Union{TableRegressionModel{<:AbstractGLM}, AbstractGLM}, - ::AutoInvLink) where {T <: AbstractFloat} +function Effects._difference_method!(eff::Vector{T}, err::Vector{T}, + model::Union{TableRegressionModel{<:AbstractGLM}, + AbstractGLM}, + ::AutoInvLink) where {T<:AbstractFloat} link = _link(model) err .*= mueta.(link, eff) eff .= linkinv.(link, eff) @@ -22,5 +23,4 @@ function Effects._difference_method!(eff::Vector{T}, err::Vector{T}, return err end - end # module diff --git a/ext/EffectsMixedModelsExt.jl b/ext/EffectsMixedModelsExt.jl index 69e978a..7d3fe2a 100644 --- a/ext/EffectsMixedModelsExt.jl +++ b/ext/EffectsMixedModelsExt.jl @@ -4,9 +4,9 @@ using Effects using MixedModels using GLM: Link, mueta, linkinv -function Effects._difference_method!(eff::Vector{T}, err::Vector{T}, - model::GeneralizedLinearMixedModel, - ::AutoInvLink) where {T <: AbstractFloat} +function Effects._difference_method!(eff::Vector{T}, err::Vector{T}, + model::GeneralizedLinearMixedModel, + ::AutoInvLink) where {T<:AbstractFloat} link = Link(model) err .*= mueta.(link, eff) eff .= linkinv.(link, eff) diff --git a/format/run.jl b/format/run.jl index 5e7150d..87bfc57 100644 --- a/format/run.jl +++ b/format/run.jl @@ -3,7 +3,7 @@ using JuliaFormatter function main() perfect = true # note: keep in sync with `.github/workflows/format-check.yml` - for d in ["src/", "test/", "docs/"] + for d in ["src/", "ext/", "test/", "docs/"] @info "...linting $d ..." dir_perfect = format(d, YASStyle()) perfect = perfect && dir_perfect diff --git a/src/regressionmodel.jl b/src/regressionmodel.jl index e1e8a57..e63ae19 100644 --- a/src/regressionmodel.jl +++ b/src/regressionmodel.jl @@ -135,22 +135,21 @@ end # in addition to the difference method # xref https://github.com/JuliaStats/GLM.jl/blob/c13577eaf3f418c58020534dd407532ee57f219b/src/glmfit.jl#L773-L783 -function _difference_method!(eff::Vector{T}, err::Vector{T}, - ::RegressionModel, - invlink) where {T <: AbstractFloat} - +function _difference_method!(eff::Vector{T}, err::Vector{T}, + ::RegressionModel, + invlink) where {T<:AbstractFloat} err .*= ForwardDiff.derivative.(invlink, eff) eff .= invlink.(eff) return eff, err end -function _difference_method!(::Vector{T}, ::Vector{T}, - ::RegressionModel, - ::AutoInvLink) where {T <: AbstractFloat} +function _difference_method!(::Vector{T}, ::Vector{T}, + ::RegressionModel, + ::AutoInvLink) where {T<:AbstractFloat} @static if VERSION < v"1.9" @error "AutoInvLink requires extensions and is thus not available on Julia < 1.9." end - throw(ArgumentError("No appropriate extension is loaded for automatic " * + throw(ArgumentError("No appropriate extension is loaded for automatic " * "determination of the inverse link for this model type")) end diff --git a/test/delta_method.jl b/test/delta_method.jl index 6d61710..7fa3c19 100644 --- a/test/delta_method.jl +++ b/test/delta_method.jl @@ -51,7 +51,7 @@ end dat[!, :vol] = dat.Volunteer .== "yes" model = glm(@formula(vol ~ Extraversion * Neuroticism), dat, Bernoulli()) design = Dict(:Extraversion => [13], - :Neuroticism => [16]) + :Neuroticism => [16]) X = [1.0 13.0 16.0 13 * 16] iv = Base.Fix1(GLM.linkinv, Link(model.model)) @static if VERSION >= v"1.9" @@ -65,18 +65,18 @@ end # compare with results from GLM.predict pred = DataFrame(predict(model.model, X; - interval=:confidence, - interval_method=:delta, - level)) + interval=:confidence, + interval_method=:delta, + level)) @test all(pred.prediction .≈ eff.vol) @test all(isapprox.(pred.lower, eff.lower; atol=0.001)) @test all(isapprox.(pred.upper, eff.upper; atol=0.001)) eff_trans = effects(design, model; level) transform!(eff_trans, - :vol => ByRow(iv), - :lower => ByRow(iv), - :upper => ByRow(iv); renamecols=false) + :vol => ByRow(iv), + :lower => ByRow(iv), + :upper => ByRow(iv); renamecols=false) # for this model, things play out nicely @test all(eff_trans.vol .≈ eff.vol) @test all(isapprox.(eff_trans.lower, eff.lower; atol=0.001)) @@ -92,7 +92,8 @@ end @test isapprox(only(eff_emm.upper), -0.292; atol=0.005) # emmeans(model, ~ neuroticism * extraversion, level=0.68, transform="response") - eff_emm_trans = effects(Dict(:Extraversion => [12.4], :Neuroticism => [11.5]), model; + eff_emm_trans = effects(Dict(:Extraversion => [12.4], :Neuroticism => [11.5]), + model; invlink) @test isapprox(only(eff_emm_trans.vol), 0.414; atol=0.005) @test isapprox(only(eff_emm_trans.err), 0.0133; atol=0.005) @@ -103,13 +104,13 @@ end @static if VERSION >= v"1.9" @testset "link function in a MixedModel" begin - model = fit(MixedModel, - @formula(use ~ 1 + age + (1|urban)), - MixedModels.dataset(:contra), + model = fit(MixedModel, + @formula(use ~ 1 + age + (1 | urban)), + MixedModels.dataset(:contra), Bernoulli(); progress=false) design = Dict(:age => -10:10) - eff_manual = effects(design, model; - invlink=Base.Fix1(GLM.linkinv, Link(model))) + eff_manual = effects(design, model; + invlink=Base.Fix1(GLM.linkinv, Link(model))) eff_auto = effects(design, model; invlink=AutoInvLink()) @test all(isapprox.(Matrix(eff_manual), Matrix(eff_auto)))