# How to fit a GLM to all (unnamed) features of arbitrary design matrix?

**URL:** <https://discourse.julialang.org/t/how-to-fit-a-glm-to-all-unnamed-features-of-arbitrary-design-matrix/20490>\
**Category:** Statistics\
**Tags:** glm\
**Created:** [February 6, 2019, 1:13am UTC](https://discourse.julialang.org/t/how-to-fit-a-glm-to-all-unnamed-features-of-arbitrary-design-matrix/20490 "2019-02-06T01:13:35Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![murphyk](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/murphyk/32/6891_2.png) [@murphyk](https://discourse.julialang.org/u/murphyk)\
**Post date:** [February 6, 2019, 1:13am UTC](https://discourse.julialang.org/t/how-to-fit-a-glm-to-all-unnamed-features-of-arbitrary-design-matrix/20490/1 "2019-02-06T01:13:35Z")

</div>

I want to call the GLM.jl library as a blackbox, which means I want to use a formula of the form “y ~ .”, where y is the target column of my dataframe, and . is all the other features.  
Specifically, what I would like to write is this:

```julia
function logreg_binary_fit_glm(X, y)
	D, N = size(X)
	Xt = permutedims(X)
	df = DataFrame(Xt)
	df[:y] = y
	# regress on all inputs :x1 ... :xd
	model = glm(@formula(y ~.), df, Binomial(), LogitLink())
	return coef(model)
end

```

Unfortunately dot syntax is not supported by the latest StatsModels v0.5, and the solution proposed [here](https://stackoverflow.com/questions/44222763/specify-only-target-variable-in-glm-jl) does not work.  
It is easy to generate the string “y ~ x1 + x2 + … xD” where D is the number of features (eg using the code below).

```julia
function make_formula_all_features(df, target)
	col_symbols = Set(names(df))
	feature_symbols = setdiff(col_symbols, Set([target]))
	feature_strings = [string(s) for s in feature_symbols]
	all_features = join(feature_strings, " + " )
	formula = string(target) * " ~ " * all_features
	return formula
end

```

However - I don’t know how to convert this to an expression to pass to the @formula macro, and applying Meta.parse to the output does not work:

```julia
n = 10
df = DataFrame(X1=randn(n), X2=randn(n), Y=randn(n))
ols = lm(@formula(Y ~ X1 + X2), df) # works
formula = make_formula_all_features(df, :Y) # "Y ~ X2 + X1"
f_expr = Meta.parse(formula) # :(Y ~ X2 + X1)
ols2 = lm(@formula(f_expr), df) # ERROR: type Symbol has no field head

```

Any ideas?

---

<div class="post-metadata">

**Author:** ![Nosferican](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nosferican/32/9275_2.png) [@Nosferican](https://discourse.julialang.org/u/Nosferican)\
**Post date:** [February 6, 2019, 4:43am UTC](https://discourse.julialang.org/t/how-to-fit-a-glm-to-all-unnamed-features-of-arbitrary-design-matrix/20490/2 "2019-02-06T04:43:27Z")

</div>

Based on example, can’t you just

```julia
glm(X::AbstractMatrix, y::AbstractVector, Binomial()) |>
    coef

```

?  
You can pass a matrix and a vector directly if you so which.

For example,

```julia
using Random
Random.seed!(0);
X = hcat(ones(100), rand(100, 2));
y = rand(0:1, 100);
fit(GeneralizedLinearModel, X, y, Binomial()) |>
    coef

```

---

<div class="post-metadata">

**Author:** ![kmmate](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kmmate/32/8795_2.png) [@kmmate](https://discourse.julialang.org/u/kmmate)\
**Post date:** [February 6, 2019, 9:18pm UTC](https://discourse.julialang.org/t/how-to-fit-a-glm-to-all-unnamed-features-of-arbitrary-design-matrix/20490/3 "2019-02-06T21:18:13Z")

</div>

First name your columns, e.g.

```julia
using DataFrames, GLM
df_y = DataFrame(y, [:yname]) # or DataFrame(y[:, :], [:yname]) if y is Array{T, 1}
df_x_names = [Symbol("x$i") for i in 1:size(x)[2]]
df_x = DataFrame(x, df_x_names)
df = hcat(df_y, df_x)

```

and then try the following workaround to, for e.g., construct a logit with main effects

```julia
lhs = :yname
rhs = Expr(:call, :+, df_x_names...)
logit = glm(@eval(@formula($(lhs) ~ $(rhs))), df, Bernoulli(), LogitLink())

```
