# Build a formula from a string

**URL:** https://discourse.julialang.org/t/build-a-formula-from-a-string/55804
**Category:** General Usage
**Tags:** statistics
**Created:** [February 22, 2021, 9:18pm UTC](https://discourse.julialang.org/t/build-a-formula-from-a-string/55804 "2021-02-22T21:18:22Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)
#### Post date: [February 22, 2021, 9:18pm UTC](https://discourse.julialang.org/t/build-a-formula-from-a-string/55804/1 "2021-02-22T21:18:22Z")

</div>

I want to build a StatsModels formula from a string. This is the closest I’ve gotten.

```julia
text = "y ~ x"
StatsModels.terms!(StatsModels.sort_terms!(StatsModels.parse!(Meta.parse(text))))
# :(($(Expr(:escape, :~)))(Term(:y), Term(:x)))

```

---

<div class="post-metadata">

### Author: ![Norman](https://avatars.discourse-cdn.com/v4/letter/n/97f17d/32.png) [@Norman](https://discourse.julialang.org/u/Norman)
#### Post date: [February 23, 2021, 5:12pm UTC](https://discourse.julialang.org/t/build-a-formula-from-a-string/55804/2 "2021-02-23T17:12:40Z")

</div>

Could you explain why it’s useful to build from a string?

---

<div class="post-metadata">

### Author: ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)
#### Post date: [February 23, 2021, 5:41pm UTC](https://discourse.julialang.org/t/build-a-formula-from-a-string/55804/3 "2021-02-23T17:41:26Z")

</div>

Since StatsModels.jl shares some syntax with other languages, I can use the same formula file from multiple tools.

---

<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: [February 23, 2021, 6:13pm UTC](https://discourse.julialang.org/t/build-a-formula-from-a-string/55804/4 "2021-02-23T18:13:36Z")

</div>

If your formulas are very basic (just multiple linear regression), you can just split your string and construct terms from that:

```julia
julia> using GLM

julia> f = "y ~ x1 + x2"
"y ~ x1 + x2"

julia> y, xs = split(f, "~")
2-element Vector{SubString{String}}:
 "y "
 " x1 + x2"

julia> term(y) ~ sum(term.(split(xs, "+")))
FormulaTerm
Response:
  y (unknown)
Predictors:
   x1 (unknown)
   x2(unknown)

```

Apart from that you’re basically looking to do what the `@formula` macro does I suppose, and that’s what you’ve got already: [https://github.com/JuliaStats/StatsModels.jl/blob/master/src/formula.jl#L63](https://github.com/JuliaStats/StatsModels.jl/blob/master/src/formula.jl#L63)

---

<div class="post-metadata">

### Author: ![jzr](https://avatars.discourse-cdn.com/v4/letter/j/eb9ed0/32.png) [@jzr](https://discourse.julialang.org/u/jzr)
#### Post date: [February 25, 2021, 9:53pm UTC](https://discourse.julialang.org/t/build-a-formula-from-a-string/55804/5 "2021-02-25T21:53:28Z")

</div>

@dave.f.kleinschmidt Is there a way I can turn this `text` into a `FormulaTerm`?

```julia
text = "y ~ x + z"
StatsModels.terms!(StatsModels.sort_terms!(StatsModels.parse!(Meta.parse(text))))
:(($(Expr(:escape, :~)))(Term(:y), ($(Expr(:escape, :+)))(Term(:x), Term(:z))))

```

---

<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: [February 25, 2021, 11:20pm UTC](https://discourse.julialang.org/t/build-a-formula-from-a-string/55804/6 "2021-02-25T23:20:15Z")

</div>

You can probably `eval` what you’ve got there, but is it absolutely necessary to be working from a string? In general, if you’re trying to do something with a string that involves calling some function depending on the contents of the string, you’re not going to be able to do it without `eval` somewhere, so you’re probably better off doing something like

```julia
@eval(@formula($(Meta.parse(text))))

```

(much as I hate to say it 🙂 )

What’s going on here is that `Meta.parse` is converting your string into a Julia `Expr`, the `$(...)` is inserting that into the expression starting with `@formula`, and then `@eval` is evaluating the whole thing. It’s basically as if you’d typed `@formula y ~ x + z` into the REPL.

It’s generally a dangerous idea to use `@eval` in scripts since it can lead to performance gotchas unless you’re VERY careful, but in this case I don’t see a way around it. The usual advice we give to people trying to construct a formula on the fly is to wrap their term symbols in `Term`s and combine them with `+`, `&`, and `~`, but if you have to be able to handle ANY formula that’s valid in R that won’t work (short of writing your own parser basically).
