Skip to content

Commit

Permalink
Merge ced6def into 658aea1
Browse files Browse the repository at this point in the history
  • Loading branch information
kleinschmidt authored Apr 10, 2023
2 parents 658aea1 + ced6def commit 03ce750
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/documenter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
- uses: actions/checkout@v2
- uses: julia-actions/setup-julia@v1
with:
version: 1.6
version: 1.8
- uses: julia-actions/julia-buildpkg@latest
- uses: julia-actions/julia-docdeploy@latest
env:
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
MixedModels v4.9.0 Release Notes
==============================
* Support `StatsModels` 0.7, drop support for `StatsModels` 0.6. [#664]
* Revise code in benchmarks to work with recent Julia and PkgBenchmark.jl [#667]
* Julia minimum compat version raised to 1.8 because of BSplineKit [#665]

Expand Down Expand Up @@ -396,5 +397,6 @@ Package dependencies
[#653]: https://github.com/JuliaStats/MixedModels.jl/issues/653
[#657]: https://github.com/JuliaStats/MixedModels.jl/issues/657
[#663]: https://github.com/JuliaStats/MixedModels.jl/issues/663
[#664]: https://github.com/JuliaStats/MixedModels.jl/issues/664
[#665]: https://github.com/JuliaStats/MixedModels.jl/issues/665
[#667]: https://github.com/JuliaStats/MixedModels.jl/issues/667
6 changes: 3 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MixedModels"
uuid = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316"
author = ["Phillip Alday <[email protected]>", "Douglas Bates <[email protected]>", "Jose Bayoan Santiago Calderon <[email protected]>"]
version = "4.8.2"
version = "4.9.0"

[deps]
Arrow = "69666777-d1a9-59fb-9406-91d4454c9d45"
Expand Down Expand Up @@ -31,7 +31,7 @@ Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
Arrow = "1, 2"
DataAPI = "1"
Distributions = "0.21, 0.22, 0.23, 0.24, 0.25"
GLM = "1.5.1"
GLM = "1.8.2"
JSON3 = "1"
LazyArtifacts = "1"
NLopt = "0.5, 0.6"
Expand All @@ -42,7 +42,7 @@ StaticArrays = "0.11, 0.12, 1"
StatsAPI = "1.5"
StatsBase = "0.31, 0.32, 0.33"
StatsFuns = "0.8, 0.9, 1"
StatsModels = "0.6.23"
StatsModels = "0.7"
StructTypes = "1"
Tables = "1"
julia = "1.8"
Expand Down
32 changes: 26 additions & 6 deletions src/randomeffectsterm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ function StatsModels.apply_schema(
schema::MultiSchema{StatsModels.FullRank},
Mod::Type{<:MixedModel},
)
lhs, rhs = t.args_parsed
lhs, rhs = t.args

isempty(intersect(StatsModels.termvars(lhs), StatsModels.termvars(rhs))) ||
throw(ArgumentError("Same variable appears on both sides of |"))
Expand All @@ -53,11 +53,21 @@ check_re_group_type(term::GROUPING_TYPE) = true
check_re_group_type(terms::Tuple{Vararg{<:GROUPING_TYPE}}) = true
check_re_group_type(x) = false

_unprotect(x) = x
for op in StatsModels.SPECIALS
@eval _unprotect(t::FunctionTerm{typeof($op)}) = t.f(_unprotect.(t.args)...)
end

# make a potentially untyped RandomEffectsTerm concrete
function StatsModels.apply_schema(
t::RandomEffectsTerm, schema::MultiSchema{StatsModels.FullRank}, Mod::Type{<:MixedModel}
)
lhs, rhs = t.lhs, t.rhs
# we need to do this here because the implicit intercept dance has to happen
# _before_ we apply_schema, which is where :+ et al. are normally
# unprotected. I tried to finagle a way around this (using yet another
# schema wrapper type) but it ends up creating way too many potential/actual
# method ambiguities to be a good idea.
lhs, rhs = _unprotect(t.lhs), t.rhs

# get a schema that's specific for the grouping (RHS), creating one if needed
schema = get!(schema.subs, rhs, StatsModels.FullRank(schema.base.schema))
Expand Down Expand Up @@ -134,11 +144,11 @@ Base.:/(a::AbstractTerm, b::AbstractTerm) = a + a & b
function StatsModels.apply_schema(
t::FunctionTerm{typeof(/)}, sch::StatsModels.FullRank, Mod::Type{<:MixedModel}
)
if length(t.args_parsed) 2
if length(t.args) 2
throw(ArgumentError("malformed nesting term: $t (Exactly two arguments required"))
end

first, second = apply_schema.(t.args_parsed, Ref(sch), Mod)
first, second = apply_schema.(t.args, Ref(sch), Mod)

if !(typeof(first) <: CategoricalTerm)
throw(
Expand Down Expand Up @@ -188,7 +198,7 @@ end
function StatsModels.apply_schema(
t::FunctionTerm{typeof(fulldummy)}, sch::StatsModels.FullRank, Mod::Type{<:MixedModel}
)
return fulldummy(apply_schema.(t.args_parsed, Ref(sch), Mod)...)
return fulldummy(apply_schema.(t.args, Ref(sch), Mod)...)
end

# specify zero correlation
Expand All @@ -207,11 +217,21 @@ zerocorr(x) = ZeroCorr(x)
# for schema extraction (from runtime-created zerocorr)
StatsModels.terms(t::ZeroCorr) = StatsModels.terms(t.term)
StatsModels.termvars(t::ZeroCorr) = StatsModels.termvars(t.term)
StatsModels.degree(t::ZeroCorr) = StatsModels.degree(t.term)
# dirty rotten no good ugly hack: make sure zerocorr ranef terms sort appropriately
# cf https://github.com/JuliaStats/StatsModels.jl/blob/41b025409af03c0e019591ac6e817b22efbb4e17/src/terms.jl#L421-L422
StatsModels.degree(t::FunctionTerm{typeof(zerocorr)}) = StatsModels.degree(only(t.args))

Base.show(io::IO, t::ZeroCorr) = Base.show(io, MIME"text/plain"(), t)
function Base.show(io::IO, ::MIME"text/plain", t::ZeroCorr)
# ranefterms already show with parens
return print(io, "zerocorr", t.term)
end

function StatsModels.apply_schema(
t::FunctionTerm{typeof(zerocorr)}, sch::MultiSchema, Mod::Type{<:MixedModel}
)
return ZeroCorr(apply_schema(t.args_parsed..., sch, Mod))
return ZeroCorr(apply_schema(only(t.args), sch, Mod))
end

function StatsModels.apply_schema(t::ZeroCorr, sch::MultiSchema, Mod::Type{<:MixedModel})
Expand Down
6 changes: 6 additions & 0 deletions test/FactorReTerm.jl
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ end
@test zc.rhs.sym == :subj
end

@testset "Amalgamation of ZeroCorr with other terms" begin
f = @formula(reaction ~ 1 + days + (1|subj) + zerocorr(days|subj))
m = LMM(f, dataset(:sleepstudy), contrasts = Dict(:days => DummyCoding()))
re = only(m.reterms)
@test length(re.cnames) == length(unique(re.cnames)) == 10
end
end

@testset "Categorical Blocking Variable" begin
Expand Down

0 comments on commit 03ce750

Please sign in to comment.