How do I force GLM to pass through a certain y intercept?

Hello all!

So I am using GLM to fit a graph of resistance vs. temperature, and I need the regression line to have an intercept of 100 Ohms at 0 degrees Centigrade. My code is -

	xdata = temp_calib_data[:Pt100][:, 1] |> Vector{Float64}
	ydata = temp_calib_data[:Pt100][:, 2] |> Vector{Float64}
	
	data = DataFrame(:X => xdata, :Y=> ydata)
	Pt100_fit = lm(@formula(Y~X), data)
	b, m = round.(coef(Pt100_fit), digits=3)
	scatter(xdata, ydata, label="Data", legend=:topleft, xlabel="Temperature (Hg)", ylabel = "Resistance Ω")
	plot!(xdata, predict(Pt100_fit), ls=:dash, label="m = $m, b=$b")

I tried using @formula(Y~100+X) however that threw an error. How can I force a certain intercept?

Thank you for the help!

Do not know the proper way, but the quick and dirty way should “work” by adding a lot of points very close to 0 with desired intercept value of 100:

N = length(xdata)
x0 = -2N*eps():eps():2N*eps()
y0 = 100 .+ 0*x0
Xd = [x0; xdata]
Yd = [y0; ydata]
data = DataFrame(:X => Xd, :Y=> Yd)
...

This might be the proper way (subtracting 100 from the data and fitting Y ~ 0 + X):

ydata = ydata .- 100
data = DataFrame(:X => xdata, :Y=> ydata)
Pt100_fit = lm(@formula(Y ~ 0 + X), data)
4 Likes

You can also do @formula(y - 100 ~ 0 + X) which will do the subtraction “lazily” (e.g., not create a new column in the table but subtract 100 from every element of y when generating the response vector).

Although to be fair, I’m not 100% sure this is a better solution than doing it in the table, because with this method you’re still going to have to remember to add 100 to predicted/fitted values to get them back on the original scale. At least if you’re predicted value is called y_min_100 you have a reminder to do that :slight_smile: (I don’t think predict will name the column based on the coefname but I could be mistaken).

2 Likes