Skip to content

Commit a8217fa

Browse files
authored
Fix intercept detector traits and hasresponse (#144)
* tests for intercepts/responses * has/omitsintercept(::FormulaTerm), widen hasresponse * use TermOrTerms for traits, instance vs. type for response * more thorough tests of intercept/response traits * use !== because we really mean it
1 parent c7f0db7 commit a8217fa

File tree

3 files changed

+80
-8
lines changed

3 files changed

+80
-8
lines changed

src/terms.jl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,14 +559,21 @@ StatsBase.coefnames(t::InteractionTerm) =
559559
################################################################################
560560
# old Terms features:
561561

562-
hasintercept(t::AbstractTerm) = InterceptTerm{true}() terms(t) || ConstantTerm(1) terms(t)
563-
omitsintercept(t::AbstractTerm) =
562+
hasintercept(f::FormulaTerm) = hasintercept(f.rhs)
563+
hasintercept(t::TermOrTerms) =
564+
InterceptTerm{true}() terms(t) ||
565+
ConstantTerm(1) terms(t)
566+
omitsintercept(f::FormulaTerm) = omitsintercept(f.rhs)
567+
omitsintercept(t::TermOrTerms) =
564568
InterceptTerm{false}() terms(t) ||
565569
ConstantTerm(0) terms(t) ||
566570
ConstantTerm(-1) terms(t)
567571

568572
hasresponse(t) = false
569-
hasresponse(t::FormulaTerm{LHS}) where {LHS} = LHS !== nothing
573+
hasresponse(t::FormulaTerm) =
574+
t.lhs !== nothing &&
575+
t.lhs !== ConstantTerm(0) &&
576+
t.lhs !== InterceptTerm{false}()
570577

571578
# convenience converters
572579
"""

test/formula.jl

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,24 @@
55
y, x1, x2, x3, a, b, c, onet = term.((:y, :x1, :x2, :x3, :a, :b, :c, 1))
66

77
## totally empty
8-
@test_broken t = @eval @formula $(:($nothing ~ 0))
9-
@test_broken hasresponse(t) == false
10-
@test_broken hasintercept(t) == false
11-
@test_broken t.rhs == ConstantTerm(0)
12-
@test_broken issetequal(terms(t), [ConstantTerm(0)])
8+
t = @formula(0 ~ 0)
9+
@test !hasresponse(t)
10+
@test !hasintercept(t)
11+
@test omitsintercept(t)
12+
@test t.rhs == ConstantTerm(0)
13+
@test issetequal(terms(t), [ConstantTerm(0)])
14+
15+
## empty lhs, intercept on rhs
16+
t = @formula(0 ~ 1)
17+
@test !hasresponse(t)
18+
@test hasintercept(t)
19+
@test !omitsintercept(t)
1320

1421
## empty RHS
1522
t = @formula(y ~ 0)
1623
@test hasintercept(t) == false
1724
@test omitsintercept(t) == true
25+
@test hasresponse(t)
1826
@test t.rhs == ConstantTerm(0)
1927
@test issetequal(terms(t), term.((:y, 0)))
2028

test/terms.jl

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,61 @@ StatsModels.apply_schema(mt::MultiTerm, sch::StatsModels.Schema, Mod::Type) =
9292

9393
@test terms2 == terms3
9494
end
95+
96+
@testset "Intercept and response traits" begin
97+
98+
has_responses = [term(:y), term(1), InterceptTerm{true}(), term(:y)+term(:z),
99+
term(:y) + term(0), term(:y) + InterceptTerm{false}()]
100+
no_responses = [term(0), InterceptTerm{false}()]
101+
102+
has_intercepts = [term(1), InterceptTerm{true}()]
103+
omits_intercepts = [term(0), term(-1), InterceptTerm{false}()]
104+
105+
using StatsModels: hasresponse, hasintercept, omitsintercept
106+
107+
a = term(:a)
108+
109+
for lhs in has_responses, rhs in has_intercepts
110+
@test hasresponse(lhs ~ rhs)
111+
@test hasintercept(lhs ~ rhs)
112+
@test !omitsintercept(lhs ~ rhs)
113+
114+
@test hasresponse(lhs ~ rhs + a)
115+
@test hasintercept(lhs ~ rhs + a)
116+
@test !omitsintercept(lhs ~ rhs + a)
117+
118+
end
119+
120+
for lhs in no_responses, rhs in has_intercepts
121+
@test !hasresponse(lhs ~ rhs)
122+
@test hasintercept(lhs ~ rhs)
123+
@test !omitsintercept(lhs ~ rhs)
124+
125+
@test !hasresponse(lhs ~ rhs + a)
126+
@test hasintercept(lhs ~ rhs + a)
127+
@test !omitsintercept(lhs ~ rhs + a)
128+
end
129+
130+
for lhs in has_responses, rhs in omits_intercepts
131+
@test hasresponse(lhs ~ rhs)
132+
@test !hasintercept(lhs ~ rhs)
133+
@test omitsintercept(lhs ~ rhs)
134+
135+
@test hasresponse(lhs ~ rhs + a)
136+
@test !hasintercept(lhs ~ rhs + a)
137+
@test omitsintercept(lhs ~ rhs + a)
138+
end
139+
140+
for lhs in no_responses, rhs in omits_intercepts
141+
@test !hasresponse(lhs ~ rhs)
142+
@test !hasintercept(lhs ~ rhs)
143+
@test omitsintercept(lhs ~ rhs)
144+
145+
@test !hasresponse(lhs ~ rhs + a)
146+
@test !hasintercept(lhs ~ rhs + a)
147+
@test omitsintercept(lhs ~ rhs + a)
148+
end
149+
150+
end
151+
95152
end

0 commit comments

Comments
 (0)