# lmer() splits binary predictor to two when I force model to pass through the origin (0 intercept)

I want to learn the effect of age on a degeneration score using linear mixed model with longitudinal data. The higher the score, the more severe the degeneration is. I assume that at age = 0, everyone should have the degeneration score = 0 (the lowest possible score), so I force the model to pass through the origin (0,0) (actually I standardized age, so there would be an intercept, but I roughly shifted the linear model back to pass through (0,0), see details in the code at the end), and the linear mixed model is a fix-intercept-random-slope model.

The problem is that when I define a binary predictor, in my case the sex variable, as a factor rather than a numeric variable, lmer() regards it as two variables and returns coefficients for both of them in the model summary. I would like to know why this happened.

Below are the model estimates when I regard sex as a factor.

Fixed effects:
Estimate Std. Error       df t value Pr(>|t|)
sexf   0.15539    0.11736 81.67705   1.324    0.189
sexm  -0.10845    0.08229 76.18574  -1.318    0.191
s.age  0.59932    0.10144 23.53187   5.908 4.62e-06 ***


Below are the model estimates when I regard sex as a numerical variable.

Fixed effects:
Estimate Std. Error       df t value Pr(>|t|)
sex   -0.11031    0.08293 78.23797  -1.330    0.187
s.age  0.59596    0.10344 24.48049   5.761 5.71e-06 ***


I know the two-variable phenomenon will disappear if I cancel the 0 + (i.e., allow for intercept) in the model (see corresponding result below).

Fixed effects:
Estimate Std. Error      df t value Pr(>|t|)
(Intercept)   0.1554     0.1174 81.6771   1.324   0.1892
sex          -0.2638     0.1432 80.1862  -1.843   0.0691 .
s.age         0.5993     0.1014 23.5319   5.908 4.62e-06 ***


Forcing the intercept to be 0 is uncommon. The only relevant post I found is: r - Random slopes regression THROUGH THE ORIGIN (0 intercept)

But that post focuses more on model fitting. I also searched other posts and did not find similar problem. Thank you for any suggestions.

Below is a replicable toy example.

#To generate a toy dataset for testing 0 intercept LMM using lmer()
library(lme4)
library(lmerTest)

set.seed(10)
#create toy variables
IID <- c(1:30)
age <- runif(30,10,70)
age2 <- age + 5
age3 <- age + 10

slope <- rnorm(30,3,1)
outcome1 <- (slope + rnorm(30,1,1))*age/100
outcome2 <- (slope + rnorm(30,1,1))*age2/100
outcome3 <- (slope + rnorm(30,1,1))*age3/100
sex <- rbinom(30,1,0.5)
T1 <- rep("T1",30)
T2 <- rep("T2",30)
T3 <- rep("T3",30)

#create toy datasets
df.t1 <- data.frame(IID, sex, age, outcome1,T1)
colnames(df.t1)[c(4,5)] <- c("outcome","Time")
df.t2 <- data.frame(IID, sex, age2, outcome2,T2)
colnames(df.t2)[c(3:5)] <- c("age","outcome","Time")
df.t3 <- data.frame(IID, sex, age3, outcome3,T3)
colnames(df.t3)[c(3:5)] <- c("age","outcome","Time")

#Long data format
DF <- rbind(df.t1, df.t2, df.t3)

DF$$s.age <- scale(DF$$age)
intercept <- mean(DF$$outcome) DF$$adj.outcome <- DF$outcome - intercept ######################################### #This would make the result different #DF$$sex <- ifelse(DF$$sex == 0, "f","m") ######################################### #linear mixed model lmm <- lmer(adj.outcome ~ 0 + sex + s.age + (0 + s.age|IID), data = DF) summary(lmm) $$$$  ## 1 Answer This is expected behaviour. If it did not estimate both levels seperately there would be a missing estimate. This doesn't really have anything to do with mixed models or lmer or standardisation. It is expected, normal, behaviour whenever the intercept is omitted from a model. To see why this is the case, consider a very simple simulated dataset: set.seed(1) dt <- expand.grid(sex = c("male", "female"), reps = 1:5) X <- model.matrix(~ sex, dt) betas <- c(1, 2) dt$Y <- X %*% betas + rnorm(nrow(dt))


So we simulate the data so that the mean for males is 1 and the mean for females is 3 (1+2).

Now we fit the model with an intercept

> summary(lm(Y ~ sex, dt))

Min      1Q  Median      3Q     Max
-1.0987 -0.6054  0.1244  0.4910  1.3170

Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept)   0.9861     0.3630   2.717   0.0264 *
sexfemale     2.2922     0.5133   4.465   0.0021 **


So we interpret this as males are estimated as 0.99 and females 2.29 + 0.99 = 3.28, which is in line with the simulated values (they are not exactly 1 and 3 due to sampling variation)

Now we fit the model without an intercept:

> summary(lm(Y ~ sex - 1, dt))

Coefficients:
Estimate Std. Error t value Pr(>|t|)
sexmale     0.9861     0.3630   2.717   0.0264 *
sexfemale   3.2783     0.3630   9.031 1.81e-05 ***


And we obtain the same estimates, as expected.

If only one level of the sex` variable was estimated, we would have no idea what the estimate for the other level was.

• If I would want to have an effect size for how much each of the sexes differs from 0, would it be adequate to use Cohen's d as it is described in Westfall et al. 2014? link. They mention in the paper that their formula does explicitly not work for dummy coded variables - but what about the case described here?
– mkks
Commented Sep 27, 2023 at 12:47