This repository was archived by the owner on Jul 7, 2020. It is now read-only.
forked from JuliaStats/MixedModels.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrandomeffectsterm.jl
More file actions
49 lines (45 loc) · 1.67 KB
/
Copy pathrandomeffectsterm.jl
File metadata and controls
49 lines (45 loc) · 1.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
struct RandomEffectsTerm <: AbstractTerm
lhs::StatsModels.TermOrTerms
rhs::StatsModels.TermOrTerms
function RandomEffectsTerm(lhs,rhs)
if isempty(intersect(StatsModels.termvars(lhs), StatsModels.termvars(rhs)))
new(lhs, rhs)
else
throw(ArgumentError("Same variable appears on both sides of |"))
end
end
end
Base.show(io::IO, t::RandomEffectsTerm) = print(io, "($(t.lhs) | $(t.rhs))")
StatsModels.is_matrix_term(::Type{RandomEffectsTerm}) = false
function StatsModels.termvars(t::RandomEffectsTerm)
vcat(StatsModels.termvars(t.lhs), StatsModels.termvars(t.rhs))
end
function StatsModels.apply_schema(t::FunctionTerm{typeof(|)}, schema::StatsModels.FullRank,
Mod::Type{<:MixedModel})
lhs, rhs = apply_schema.(t.args_parsed, Ref(schema), Mod)
RandomEffectsTerm(MatrixTerm(lhs), rhs)
end
function StatsModels.modelcols(t::RandomEffectsTerm, d::NamedTuple)
lhs = t.lhs
z = Matrix(transpose(modelcols(lhs, d)))
cnames = coefnames(lhs)
T = eltype(z)
S = size(z, 1)
grp = t.rhs
m = reshape(1:abs2(S), (S, S))
inds = sizehint!(Int[], (S * (S + 1)) >> 1)
for j in 1:S, i in j:S
push!(inds, m[i,j])
end
invindex = grp.contrasts.invindex
refs = convert(Vector{Int32}, getindex.(Ref(invindex), d[grp.sym]))
J = Int32.(1:length(refs))
II = refs
if S > 1
J = repeat(J, inner=S)
II = Int32.(vec([(r - 1)*S + j for j in 1:S, r in refs]))
end
ReMat{T,S}(grp, refs, isa(cnames, String) ? [cnames] : collect(cnames),
z, z, LowerTriangular(Matrix{T}(I, S, S)), inds,
sparse(II, J, vec(z)), Matrix{T}(undef, (S, length(invindex))))
end