hoping someone can help me with what (on the face of it) appears to be a relatively simple problem but which I can't current code out.
Basically, I would like to fit a GLM in R with a simple two-way interaction between a two-level factor and a continuous covariate, but fix the slope coefficient for one of the factor levels to be zero (while still estimating its intercept). I want to apply the method to a piecewise regression on count data (y) where for a priori reasons we 'know' there is no relationship between y and x at values of x > k but that there is a relationship at x < k. The aim is to find k by iteratively searching for the value that gives the lowest mean square error in the fitted GLMs. A simple reprex below.
First simulate some data.
set.seed(5) k = 7 x = runif(30,0,20) # Simulate some values of x y = ifelse(x<k,-0.2*x+3.5,0*x+1) # Calculate y on scale of linear predictor y = exp(y) # Convert to response scale y = sapply(y,function(i) rpois(1,i)) # Generate some counts plot(y~x)
Now fit a GLM using a factor to identify whether x is greater or less than k
data = data.frame(y=y,x=x,fac= x<k) model = glm(y ~ fac + x:fac,family='poisson',data=data) summary(model) Coefficients: Estimate Std. Error z value Pr(>|z|) (Intercept) 1.17370 0.55206 2.126 0.0335 * facTRUE 2.59354 0.59167 4.383 1.17e-05 *** facFALSE:x -0.01833 0.03822 -0.479 0.6316 facTRUE:x -0.25126 0.05456 -4.605 4.12e-06 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
The model does a pretty good job at recreating the coefficients used to simulate the data. However, it would probably improve the performance of the subsequent search to find k if I could fix the slope coefficient for facFALSE:x to be zero. Normally I would use an offset term for this but I can't work out how to apply it to just one level of the factor. I know there are other solutions to doing this type of segmented regression using various R packages but for my application it would be beneficial to be able to code it from first principles in this way. I'm sure there is a simple solution so any pointers gratefully received.