diff --git a/Project.toml b/Project.toml index fa602d5..0ffeed6 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "AnovaBase" uuid = "946dddda-6a23-4b48-8e70-8e60d9b8d680" authors = ["Yu-Fong Peng "] -version = "0.7.4" +version = "0.7.5" [deps] Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" @@ -14,6 +14,6 @@ StatsModels = "3eaba693-59b7-5ba5-a881-562e759f1c8d" [compat] Distributions = "0.23, 0.24, 0.25" Reexport = "0.2, 1" -StatsBase = "0.33" -StatsModels = "0.6" -julia = "1.6, 1.7, 1.8" \ No newline at end of file +StatsBase = "0.33, 0.34" +StatsModels = "0.7" +julia = "1.6, 1.7, 1.8, 1.9" \ No newline at end of file diff --git a/docs/make.jl b/docs/make.jl index 25c7c33..0bce120 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -11,9 +11,7 @@ makedocs( "Examples_MixedModels.md", "Examples_FixedEffectModels.md" ], - "Interfacing AnovaBase.jl" => [ - "Interface.md" - ], + "Interface.md", "Algorithm" => [ "Algorithm_AnovaGLM.md", "Algorithm_AnovaMixedModels.md", diff --git a/docs/src/Interface.md b/docs/src/Interface.md index 1123bb6..c3bbc3d 100644 --- a/docs/src/Interface.md +++ b/docs/src/Interface.md @@ -1,4 +1,4 @@ -# Interface +# Interfacing AnovaBase.jl Given model types `SomeModel` and `OtherModel`, the following functions have to be defined or used. ## [anova](./AnovaBase.md#AnovaBase.anova-Tuple{Type{<:GoodnessOfFit},%20AnovaModel}) @@ -62,4 +62,4 @@ This function is not essential for ANOVA; it is just for convenience to create n `AnovaBase` provides a lot of functions to work on formula, terms and contrasts. See [Developer utility](./AnovaBase.md#Developer-utility) ## Other function -* [`dof_residual`](./AnovaBase.md#AnovaBase.dof_residual-Tuple{AnovaResult}) applies `dof_residual` to all models by default. If `dof_residual(::SomeModel)` is not valid for ANOVA, customize `dof_residual(::AnovaResult{<: AnovaModel{SomeModel}})` alternatively. \ No newline at end of file +* [`dof_residual`](./AnovaBase.md#StatsAPI.dof_residual-Tuple{AnovaResult}) applies `dof_residual` to all models by default. If `dof_residual(::SomeModel)` is not valid for ANOVA, customize `dof_residual(::AnovaResult{<: AnovaModel{SomeModel}})` alternatively. \ No newline at end of file diff --git a/src/AnovaBase.jl b/src/AnovaBase.jl index b5522a4..aa6591c 100644 --- a/src/AnovaBase.jl +++ b/src/AnovaBase.jl @@ -3,7 +3,7 @@ module AnovaBase using Statistics, Distributions, Reexport, Printf @reexport using StatsModels import StatsBase: fit!, fit, dof, dof_residual, deviance, nobs, vcov, coeftable -import StatsModels: TableRegressionModel, vectorize, collect_matrix_terms, coefnames, formula, asgn, TupleTerm +import StatsModels: TableRegressionModel, vectorize, collect_matrix_terms, coefnames, formula, asgn, TupleTerm, hasintercept import Base: show export @@ -132,7 +132,7 @@ function FullModel(model::RegressionModel, type::Int, null::Bool, test_intercept #err2 = ArgumentError("Invalid set of model specification for ANOVA; all coefficents are aliased with 1.") preds = predictors(model) pred_id = collect(eachindex(preds)) - has_intercept(preds) || popfirst!(pred_id) + hasintercept(preds) || popfirst!(pred_id) isempty(pred_id) && throw(err1) # ~ 0 if type ≡ 1 # ~ 0 + A + B..., ~ 1 + B..., ~ B as null diff --git a/src/term.jl b/src/term.jl index 8ee7641..2f80a3a 100644 --- a/src/term.jl +++ b/src/term.jl @@ -1,14 +1,5 @@ # Function related to terms -""" - has_intercept() - -Return `true` if `InterceptTerm{true}` is in the terms. -""" -has_intercept(f::FormulaTerm) = has_intercept(f.rhs) -has_intercept(f::MatrixTerm) = has_intercept(f.terms) -has_intercept(f::TupleTerm) = has_intercept(first(f)) -has_intercept(::InterceptTerm{H}) where H = H -has_intercept(::AbstractTerm) = false +@deprecate has_intercept hasintercept """ any_not_aliased_with_1() @@ -201,7 +192,7 @@ Set{Int64} with 3 elements: select_super_interaction(f::MatrixTerm, id::Int) = select_super_interaction(f.terms, id) function select_super_interaction(f::TupleTerm, id::Int) s = id ≡ 1 ? Set(eachindex(f)) : Set([idn for idn in eachindex(f) if isinteract(f, id, idn)]) - has_intercept(f) || filter!(!=(1), s) + hasintercept(f) || filter!(!=(1), s) s end @@ -209,7 +200,7 @@ end select_sub_interaction(f::MatrixTerm, id::Int) = select_sub_interaction(f.terms, id) function select_sub_interaction(f::TupleTerm, id::Int) s = id ≡ 1 ? Set(Int[]) : Set([idn for idn in eachindex(f) if isinteract(f, idn, id)]) - has_intercept(f) || filter!(!=(1), s) + hasintercept(f) || filter!(!=(1), s) s end @@ -217,7 +208,7 @@ end select_not_super_interaction(f::MatrixTerm, id::Int) = select_not_super_interaction(f.terms, id) function select_not_super_interaction(f::TupleTerm, id::Int) s = id ≡ 1 ? Set(Int[]) : Set([idn for idn in eachindex(f) if !isinteract(f, id, idn)]) - has_intercept(f) || filter!(!=(1), s) + hasintercept(f) || filter!(!=(1), s) s end @@ -225,7 +216,7 @@ end select_not_sub_interaction(f::MatrixTerm, id::Int) = select_not_sub_interaction(f.terms, id) function select_not_sub_interaction(f::TupleTerm, id::Int) s = id ≡ 1 ? Set(eachindex(f)) : Set([idn for idn in eachindex(f) if !isinteract(f, idn, id)]) - has_intercept(f) || filter!(!=(1), s) + hasintercept(f) || filter!(!=(1), s) s end diff --git a/test/runtests.jl b/test/runtests.jl index 396f066..f63f3ed 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -75,7 +75,7 @@ anovatable(::AnovaResult{<: FullModel{StatsModels.TableRegressionModel{Int64, Ma 1, 1, Int), mm) conterm = ContinuousTerm(:y, 0.0, 0.0, 0.0, 0.0) - fterm = FunctionTerm(log, x->log(x), (:t, ), :(log(t)), []) + fterm = FunctionTerm(log, [Term(:t)], :(log(t))) caterm() = CategoricalTerm(:x, StatsModels.ContrastsMatrix(StatsModels.FullDummyCoding(), [1, 2, 3])) caterm(i) = CategoricalTerm(Symbol("x$i"), StatsModels.ContrastsMatrix(StatsModels.DummyCoding(), [1, 2, 3])) global model5 = StatsModels.TableRegressionModel( @@ -188,7 +188,7 @@ anovatable(::AnovaResult{<: FullModel{StatsModels.TableRegressionModel{Int64, Ma end global f = FormulaTerm(conterm, MatrixTerm((InterceptTerm{true}(), caterm(), fterm, InteractionTerm((caterm(), fterm))))) @testset "term.jl" begin - @test AnovaBase.has_intercept(f.rhs) + @test AnovaBase.hasintercept(f.rhs) @test AnovaBase.any_not_aliased_with_1(f.rhs) @test !AnovaBase.any_not_aliased_with_1(MatrixTerm((InterceptTerm{true}(), caterm(), caterm(1), caterm(2), InteractionTerm((caterm(), caterm(1), caterm(2)))))) @test AnovaBase.any_not_aliased_with_1(MatrixTerm((InterceptTerm{true}(), caterm(), conterm, fterm, InteractionTerm((caterm(), conterm, fterm)))))