@@ -23,6 +23,8 @@ library("nlme")
2323library("lmerTest")
2424library("MASS")
2525library("MCMCglmm")
26+ library("mgcv")
27+ library("parallelly")
2628library("performance")
2729library("ggplot2")
2830```
@@ -74,6 +76,12 @@ mydata$ageMonthsCentered <- mydata$age - min(mydata$age, na.rm = TRUE)
7476
7577mydata$ageYearsCentered <- mydata$ageMonthsCentered / 12
7678mydata$ageYearsCenteredSquared <- mydata$ageYearsCentered ^ 2
79+
80+ mydata$sex <- factor(
81+ mydata$female,
82+ levels = c(0, 1),
83+ labels = c("male", "female")
84+ )
7785```
7886
7987# Estimator: ML or REML
@@ -533,6 +541,120 @@ summary(MCMCglmmModel)
533541
534542# Nonlinear Mixed Models {#nonlinear}
535543
544+ ## Generalized Additive Mixed Model {#gamm}
545+
546+ ### Fit Model
547+
548+ ``` {r}
549+ #| label: parallel-cores-mixed-models
550+ #| include: false
551+
552+ num_cores <- parallelly::availableCores()
553+ num_true_cores <- parallelly::availableCores(logical = FALSE)
554+ ```
555+
556+ ``` {r}
557+ #| eval: false
558+
559+ num_cores <- parallelly::availableCores() - 1
560+ num_true_cores <- parallelly::availableCores(logical = FALSE) - 1
561+ ```
562+
563+ ``` {r}
564+ #| label: gam-mixed-models
565+
566+ gamModel <- mgcv::gam(
567+ math ~ s(ageYearsCentered, by = sex) + s(ageYearsCentered, id, bs = "fs"),
568+ data = mydata,
569+ nthreads = num_cores
570+ )
571+
572+ summary(gamModel)
573+ ```
574+
575+ ### Prototypical Growth Curve
576+
577+ ``` {r}
578+ newData <- expand.grid(
579+ female = c(0, 1),
580+ ageYears = seq(from = min(mydata$ageYears, na.rm = TRUE), to = max(mydata$ageYears, na.rm = TRUE), length.out = 10000))
581+
582+ newData$ageYearsCentered <- newData$ageYears - min(newData$ageYears)
583+ newData$ageYearsCenteredSquared <- newData$ageYearsCentered ^ 2
584+
585+ newData$sex <- NA
586+ newData$sex[which(newData$female == 0)] <- "male"
587+ newData$sex[which(newData$female == 1)] <- "female"
588+ newData$sex <- as.factor(newData$sex)
589+
590+ # add a dummy id
591+ newData$id <- mydata$id[1]
592+
593+ newData$predictedValue <- predict(
594+ gamModel,
595+ newdata = newData,
596+ exclude = "s(ageYearsCentered,id)"
597+ )
598+
599+ ggplot(
600+ newData,
601+ aes(
602+ x = ageYearsCentered,
603+ y = predictedValue,
604+ color = sex
605+ )
606+ ) +
607+ geom_line(linewidth = 1.5) +
608+ labs(
609+ x = "Age (Centered)",
610+ y = "Math Score",
611+ color = "Sex"
612+ )
613+ ```
614+
615+ ### Individuals' Growth Curves
616+
617+ ``` {r}
618+ mydata$predictedValue <- predict(
619+ gamModel,
620+ newdata = mydata
621+ )
622+
623+ ggplot(
624+ data = mydata,
625+ mapping = aes(
626+ x = ageYears,
627+ y = predictedValue,
628+ group = factor(id))) +
629+ xlab("Age (Years)") +
630+ ylab("Math Score") +
631+ geom_line()
632+ ```
633+
634+ ##### Individuals' Trajectories Overlaid with Prototypical Trajectory
635+
636+ ``` {r}
637+ ggplot(
638+ data = mydata,
639+ mapping = aes(
640+ x = ageYears,
641+ y = predictedValue,
642+ group = factor(id))) +
643+ xlab("Age (Years)") +
644+ ylab("Math Score") +
645+ geom_line() +
646+ geom_line(
647+ data = newData,
648+ mapping = aes(
649+ x = ageYears,
650+ y = predictedValue,
651+ group = sex,
652+ color = sex),
653+ linewidth = 2)
654+ ```
655+
656+ ## Asymptotic Growth {#nonlinearAsymptotic}
657+
536658``` {r}
537659nonlinearModel <- nlme(
538660 height ~ SSasymp(age, Asym, R0, lrc),
0 commit comments