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)
#Standardization and adjustment
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)
```