# StatsModels R-like formula for a general quadratic model

**URL:** <https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441>\
**Category:** Statistics\
**Created:** [July 10, 2021, 11:29pm UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441 "2021-07-10T23:29:14Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![joergbuchwald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joergbuchwald/32/13112_2.png) [@joergbuchwald](https://discourse.julialang.org/u/joergbuchwald)\
**Post date:** [July 10, 2021, 11:29pm UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/1 "2021-07-10T23:29:14Z")

</div>

Hi!  
I want to construct a regression formula for a general quadratic model without writing out each interaction term separately. I remember that for the python Statsmodels package I could do something like:

```julia
y~np.power(a,2)+np.power(b,2)+np.power(c,2)+(a+b+c)**2

```

In julia, I thought the analogon could look like

```julia
@formula(y ~ a^2+b^2+c^2 +(a+b+c)^2) .

```

Here, however, the last term is interpreted as a single parameter and not as

```julia
@formula(y ~ a^2+b^2+c^2 + a*b+b*c+a*c) 

```

Is there an easy way to account for all combinatorial interactions?  
(for 3 parameters the difference is obviously no big deal, but I’m looking for a solution for an arbitrary number of parameters)

---

<div class="post-metadata">

**Author:** ![xiaodai](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xiaodai/32/15937_2.png) [@xiaodai](https://discourse.julialang.org/u/xiaodai)\
**Post date:** [July 11, 2021, 1:54am UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/2 "2021-07-11T01:54:11Z")

</div>

Doesn’t seem to say in the manual [Modeling tabular data · StatsModels.jl](https://juliastats.org/StatsModels.jl/stable/formula/#Modeling-tabular-data)

But I was curious.

I think you can do it via constructing terms directly.

```julia
using Base.Iterators
function allinteractions(terms::Vector{Symbol})
    tmp = sum(Term.(terms))
    tmp + sum([t1&t2 for(t1, t2) in Iterators.product(tmp, tmp)])
end

formula = Term(:y)~allinteractions([:a, :b, :c])
using GLM
lm(formula, df)

```

---

<div class="post-metadata">

**Author:** ![joergbuchwald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joergbuchwald/32/13112_2.png) [@joergbuchwald](https://discourse.julialang.org/u/joergbuchwald)\
**Post date:** [July 11, 2021, 2:32pm UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/3 "2021-07-11T14:32:59Z")

</div>

> [@xiaodai](#):
>
> `formula = Term(:y)~allinteractions([:a, :b, :c])`

Thx, but this formula still needs to be cleaned-up for permutations which it is not accounting for.

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [July 11, 2021, 4:39pm UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/4 "2021-07-11T16:39:57Z")

</div>

Just to clarify (as I’m not familiar with Python’s formula syntax), are you looking for

```julia
julia> sum(length(x) == 1 ? term(only(x)) : (&)(term.(x)...) for x ∈ combinations([:a, :b, :c]))
a(unknown)
b(unknown)
c(unknown)
a(unknown) & b(unknown)
a(unknown) & c(unknown)
b(unknown) & c(unknown)
a(unknown) & b(unknown) & c(unknown)

```

but with all terms in the formula squared?

---

<div class="post-metadata">

**Author:** ![joergbuchwald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joergbuchwald/32/13112_2.png) [@joergbuchwald](https://discourse.julialang.org/u/joergbuchwald)\
**Post date:** [July 11, 2021, 5:05pm UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/5 "2021-07-11T17:05:29Z")

</div>

This comes closer, but maybe without the last term, as I would consider it to be of order 3.  
So

```julia
@formula(y ~ a^2+b^2+c^2 + a&b+b&c+a&c + a + b + c +1)

```

---

<div class="post-metadata">

**Author:** ![joergbuchwald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joergbuchwald/32/13112_2.png) [@joergbuchwald](https://discourse.julialang.org/u/joergbuchwald)\
**Post date:** [July 11, 2021, 6:39pm UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/6 "2021-07-11T18:39:53Z")

</div>

> [@nilshg](#):
>
> `sum(length(x) == 1 ? term(only(x)) : (&)(term.(x)...) for x ∈ combinations([:a, :b, :c]))`

Based on your solution, the problem can be solved by

```julia
a = sum(InteractionTerm(term.((only(x),only(x)))) for x ∈ combinations([:a, :b, :c],1))
b = sum((&)(term.(x)...) for x ∈ combinations([:a, :b, :c],2))
c = sum(term(only(x)) for x ∈ combinations([:a, :b, :c],1))
formula = Term(:y) ~ a + b +c + ConstantTerm(1)

```

Although an even shorter form would be nice indeed.

---

<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:** [August 7, 2021, 2:30am UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/7 "2021-08-07T02:30:08Z")

</div>

If you’re feeling brave, there’s a prototype implementation of the `^` syntax you’d like in this not-quite-package: [GitHub - kleinschmidt/RegressionFormulae.jl](https://github.com/kleinschmidt/RegressionFormulae.jl)

The gist of it is that you need to implement a `apply_schema(::FunctionTerm{typeof(^)}, ...)` method that transforms that terms into the representation you want. That’s what’s in [this file](https://github.com/kleinschmidt/RegressionFormulae.jl/blob/master/src/power.jl) (along with definitions that allow you to do things like `(term(:a) + term(:b) + term(:c))^2` at run time, in addition to `@formula(y ~ (a+b+c)^2`

---

<div class="post-metadata">

**Author:** ![joergbuchwald](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joergbuchwald/32/13112_2.png) [@joergbuchwald](https://discourse.julialang.org/u/joergbuchwald)\
**Post date:** [August 7, 2021, 10:46pm UTC](https://discourse.julialang.org/t/statsmodels-r-like-formula-for-a-general-quadratic-model/64441/8 "2021-08-07T22:46:22Z")

</div>

Ah, cool. Thx!
