Without a minimal working example of your data, I used the builtin iris data. Here I pretended that the Species were different subjects for the sake of demonstration.
library(lme4)
library(ggplot2)
fit.iris <- lmer(Sepal.Width ~ Sepal.Length + I(Sepal.Length^2) + (1|Species), data = iris)
I also use two extra packages for simplicity, broom
and dplyr
. augment
from broom
does the same thing as you did above with ..., fitted.re=fitted(MensHG.fm2)
, but with some extra bells and whistles. I also use dplyr::select
, but that's not strictly needed, depending on the output you desire (the difference between Fig 2 vs Fig 3).
library(broom)
library(dplyr)
augment(fit.iris)
# output here truncated for simplicity
Sepal.Width Sepal.Length I.Sepal.Length.2. Species .fitted .resid .fixed ...
1 3.5 5.1 26.01 setosa 3.501175 -0.001175181 2.756738
2 3.0 4.9 24.01 setosa 3.371194 -0.371193601 2.626757
3 3.2 4.7 22.09 setosa 3.230650 -0.030649983 2.486213
4 3.1 4.6 21.16 setosa 3.156417 -0.056417409 2.411981
5 3.6 5.0 25 setosa 3.437505 0.162495354 2.693068
6 3.9 5.4 29.16 setosa 3.676344 0.223656271 2.931907
ggplot(augment(fit.iris),
aes(Sepal.Length, Sepal.Width)) +
geom_line(#data = augment(fit.iris) %>% select(-Species),
aes(y = .fixed, color = "population"), size = 2) +
geom_line(aes(y = .fitted, color = "subject", group = Species), size = 2) +
geom_point() +
#facet_wrap(~Species, ncol = 2) +
theme(legend.position = c(0.75,0.25))
Note that I #
-commented two statements: data = ...
and facet_wrap(...)
. With those lines commented out, you get an output like this:

You have your population smooth (.fixed
for fixed-effects) across the whole range, and then you have group smooths that show the fitted model values (.fitted
), taking into account the subject-level intercepts.
Then you can show this in facets by taking out the second #
-comment mark in the code snippet:

This is the same, but since the fitted values only exist within the range of the original data for each subject-level panel, the population smooth is truncated to just that range.
To get around that, we can remove the first #
-comment mark:
