R: Adding group and individual polynomial trend lines to a GMM plot

1.3k views Asked by At

I am struggling with how to add both individual and a group trend line to my plots. (R and using ggplot2).

Here is the code that I am using:

MensHG.fm2=lmer(HGNewtons~Temperature+QuadTemp+Run+(1|Subject),MenstrualData) #model

plot.hg<-data.frame(MensHG.fm2@frame,fitted.re=fitted(MensHG.fm2))

g1<-ggplot(plot.hg,aes(x=Temperature,y=HGNewtons))+geom_point()

g2<-g1+facet_wrap(~Subject, nrow=6)+ylab(bquote('HG MVF (N)'))+xlab(bquote('Hand ' ~T[sk] ~(degree*C)))

g3<-g2+geom_smooth(method="glm", formula=y~ploy(x,2), se=FALSE) #This gives me my individual trendlines

Now I want to put on the trendline for the g1 part of the data (ie overall trend) onto each of my individual plots - what is the best way to do this? I can see the trend if I use the code:

g5=g1+geom_smooth(method="glm", formula=y~poly(x,2), se=FALSE)

enter image description here

BUT this trendline disspears as soon as I do the facet-wrap (I get the same output as g3)

It does not appear to solve the problem by using: g4<-g3+geom_smooth(data=MensHG.fm2)

1

There are 1 answers

0
Brian On BEST ANSWER

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:

enter image description here

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:

enter image description here

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:

enter image description here