# ModelFrame contrast & factors in StatsModels in v"0.6.x"

**URL:** <https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272>\
**Category:** Statistics\
**Created:** [September 1, 2019, 9:36pm UTC](https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272 "2019-09-01T21:36:23Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![PharmCat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pharmcat/32/6953_2.png) [@PharmCat](https://discourse.julialang.org/u/PharmCat)\
**Post date:** [September 1, 2019, 9:36pm UTC](https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272/1 "2019-09-01T21:36:25Z")

</div>

Hello! I’m confused. In StatsModels 0.5.0 i can get contrasts levels simply:

```julia
ModelFrame.contrasts[:name].levels

```

How can I do it now?

And how can i get predictors list?

---

<div class="post-metadata">

**Author:** ![PharmCat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pharmcat/32/6953_2.png) [@PharmCat](https://discourse.julialang.org/u/PharmCat)\
**Post date:** [September 1, 2019, 9:59pm UTC](https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272/2 "2019-09-01T21:59:44Z")

</div>

Ok, I just found how to get it by number:

```julia
ModelFrame.f.rhs.terms[2].contrasts.contrasts

```

How to get contrasts by Symbol (column name)?

---

<div class="post-metadata">

**Author:** ![PharmCat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pharmcat/32/6953_2.png) [@PharmCat](https://discourse.julialang.org/u/PharmCat)\
**Post date:** [September 2, 2019, 9:45pm UTC](https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272/3 "2019-09-02T21:45:28Z")

</div>

Ok, i made some solution to do this:

```julia
#Find all factors
function findtermnames(MF::ModelFrame)
    a = Array{Symbol, 1}(undef, 0)
    l = length(MF.f.rhs.terms)
    for i = 1:l
        if isa(MF.f.rhs.terms[i], InterceptTerm) continue end
        push!(a, MF.f.rhs.terms[i].sym)
    end
    return Tuple(a)
end
#Find by Symbol
function findterm(MF::ModelFrame, symbol::Symbol)::Int
    l = length(MF.f.rhs.terms)
    for i = 1:l
        if isa(MF.f.rhs.terms[i], InterceptTerm) continue end
        if MF.f.rhs.terms[i].sym == symbol return i end
    end
    return 0
end
#Return length by Symbol
function termmodellen(MF::ModelFrame, symbol::Symbol)::Int
    id = findterm(MF, symbol)
    return length(MF.f.rhs.terms[id].contrasts.termnames)
end

```

Is it right way?

Is it any “build in” function that i could not find to do this?

---

<div class="post-metadata">

**Author:** ![PharmCat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pharmcat/32/6953_2.png) [@PharmCat](https://discourse.julialang.org/u/PharmCat)\
**Post date:** [September 11, 2019, 10:42pm UTC](https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272/4 "2019-09-11T22:42:20Z")

</div>

Ok!  
For example, I can get coefficient names by coefnames() , how to get facor or term for each coefficient in list?

---

<div class="post-metadata">

**Author:** ![dave.f.kleinschmidt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dave.f.kleinschmidt/32/55_2.png) [@dave.f.kleinschmidt](https://discourse.julialang.org/u/dave.f.kleinschmidt)\
**Post date:** [September 28, 2019, 9:21am UTC](https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272/5 "2019-09-28T09:21:36Z")

</div>

I posted on the [github issue you opened](https://github.com/JuliaStats/StatsModels.jl/issues/149), but I’ll copy my response here for posterity 🙂 At a high level, the internal structure of 0.5 and 0.6+ is fundamentally different (you can see the heart of the changes in the [Terms 2.0: Son of Terms PR](https://github.com/JuliaStats/StatsModels.jl/pull/71), or read the discourse posts or latest docs)

You can get the `ContrastsMatrix` for each categorical term like this:

```julia
julia> using StatsModels, StatsBase

julia> data = (a = rand(10), b = sample(1:3, 10), c = sample([:a, :b, :c], 10));

julia> f = apply_schema(@formula(0 ~ a + b + c), schema(data, Dict(:b=>CategoricalTerm)))
FormulaTerm
Response:
  0
Predictors:
  a(continuous)
  b(DummyCoding:3→2)
  c(DummyCoding:3→2)

julia> contrasts = [t.contrasts for t in terms(f.rhs) if t isa CategoricalTerm]
2-element Array{StatsModels.ContrastsMatrix{DummyCoding,T} where T,1}:
 StatsModels.ContrastsMatrix{DummyCoding,Int64}([0.0 0.0; 1.0 0.0; 0.0 1.0], [2, 3], [1, 2, 3], DummyCoding(nothing, nothing), Dict(2 => 2,3 => 3,1 => 1))                     
 StatsModels.ContrastsMatrix{DummyCoding,Symbol}([0.0 0.0; 1.0 0.0; 0.0 1.0], Symbol[:b, :c], Symbol[:a, :b, :c], DummyCoding(nothing, nothing), Dict(:a => 1,:b => 2,:c => 3))

```

The fields of this struct give you all the information about the contrast coding:

```julia
julia> cm = contrasts[end];

julia> cm.matrix
3×2 Array{Float64,2}:
 0.0 0.0
 1.0 0.0
 0.0 1.0

julia> cm.levels
3-element Array{Symbol,1}:
 :a
 :b
 :c

julia> cm.termnames
2-element Array{Symbol,1}:
 :b
 :c

```

I _think_ by “contrast vectors” you mean the columns of the `.matrix` field, each of which corresponds to one column in the model matrix.

If you want to have a symbol-indexable version of this, then you’ll first need to construct a symbol-to-term mapping, like

```julia
julia> Dict(t.sym => t for t in terms(f) if hasproperty(t, :sym))
Dict{Symbol,AbstractTerm} with 3 entries:
  :a => a
  :b => b
  :c => c

```

This gives you all the terms, but you can also restrict to `CategoricalTerm`s which have contrasts and extract the `ContrastsMatrix` structs all in one go:

```julia
julia> Dict(t.sym => t.contrasts for t in terms(f) if t isa CategoricalTerm)
Dict{Symbol,StatsModels.ContrastsMatrix{DummyCoding,T} where T} with 2 entries:
  :b => ContrastsMatrix{DummyCoding,Int64}([0.0 0.0; 1.0 0.0; 0.0 1.0], [2, 3], [1, 2, 3], DummyCoding(nothing, nothing), Dict(2=>2,3=>3,1=>1))
  :c => ContrastsMatrix{DummyCoding,Symbol}([0.0 0.0; 1.0 0.0; 0.0 1.0], Symbol[:b, :c], Symbol[:a, :b, :c], DummyCoding(nothing, nothing), Dict(:a=>1,:b=>2,:c=>3))

```

---

<div class="post-metadata">

**Author:** ![dave.f.kleinschmidt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dave.f.kleinschmidt/32/55_2.png) [@dave.f.kleinschmidt](https://discourse.julialang.org/u/dave.f.kleinschmidt)\
**Post date:** [September 28, 2019, 9:25am UTC](https://discourse.julialang.org/t/modelframe-contrast-factors-in-statsmodels-in-v-0-6-x/28272/6 "2019-09-28T09:25:21Z")

</div>

Also, the `ModelFrame` struct is largely superfluous for these purposes, all you need is the `FormulaTerm`, which you can access with the `mf.f` field. The `ModelFrame`/`ModelMatrix` interface is included mostly for backwards compatibility, but is likely to be dropped in favor of having modeling packages use the `@formula`, `schema`, `apply_schema`, `modelcols` API directly, which provides more flexibility in how terms are handled (the MixedModels.jl package is a good example of the benefits this brings)
