Chapter 4 Latent growth curves
4.1 Discovering growth curves
we want to identify the trajectory and predict who has the more positive or more negative trajectory
the overall trajectory is referred to as a fixed effect - it is what would happen if everybody had the same trajectory
difference in an individual’s trajectory from the overall trajectory is referred to as a random effect
4.2 A simple growth curve model
- the intercept and slope are treated as latent variables
4.3 An example of a linear latent growth curve
library(haven)
<- read_dta("bmiworking.dta")
nlsy.data
library(tidyverse)
glimpse(nlsy.data)
## Rows: 1,667
## Columns: 38
## $ id <dbl> 1437, 5601, 6951, 4852, 1380, 8535, 2639, 2415, 3161, 7685, …
## $ bmi97 <dbl> 22.45694, 25.32855, 26.25490, 19.57563, 20.67213, 25.08542, …
## $ bmi98 <dbl> NA, 26.21416, 25.82449, 21.28460, 19.52390, 23.67245, 24.126…
## $ bmi99 <dbl> NA, 26.74553, 27.54612, 20.52444, 19.36837, 25.84016, 25.457…
## $ bmi00 <dbl> NA, 27.27690, 26.11143, 22.70773, 20.08571, 25.10714, 24.126…
## $ bmi01 <dbl> NA, 27.61524, 36.91451, 21.92471, 22.95510, 28.69388, 24.958…
## $ bmi02 <dbl> NA, 26.21416, 35.86735, 22.70773, 22.14871, NA, 24.95858, NA…
## $ bmi03 <dbl> NA, NA, 43.32937, 23.64736, 22.95510, 34.84730, 24.95858, NA…
## $ bmi05 <dbl> NA, 24.97430, 42.56920, 22.70773, 25.10187, 33.22306, 26.955…
## $ bmi06 <dbl> NA, 28.89542, 42.75388, 22.70773, 25.10187, 33.22306, 26.955…
## $ bmi07 <dbl> NA, 28.69388, 43.93750, 22.04477, 28.05503, 33.96135, 26.622…
## $ bmi08 <dbl> NA, 28.33963, 43.90163, 21.92471, 28.05503, 34.99496, NA, NA…
## $ bmi09 <dbl> NA, 29.75661, 46.77102, 21.92471, 28.05503, 32.42408, NA, 22…
## $ deswgt97 <dbl+lbl> 3, 4, 4, 3, 3, 4, 3, 3, 4, 3, 3, 3, 3, 2, 4, 3, 3, 3, 4,…
## $ deswgt98 <dbl> NA, 3, 4, 3, 4, 4, 4, 4, 3, 2, 3, NA, 3, 2, 4, 3, 4, 3, 5, 3…
## $ deswgt00 <dbl> NA, 3, 2, 3, 4, 4, 4, NA, NA, 2, 3, 3, 4, 2, 2, NA, 4, 2, 5,…
## $ deswgt01 <dbl> NA, 4, 1, 3, 4, 5, 4, NA, 4, 2, 3, NA, 3, 3, 4, 3, 4, 3, 4, …
## $ deswgt02 <dbl> NA, 4, 2, 3, 4, 5, 4, NA, 4, 2, 4, NA, NA, 3, 4, 3, 4, 3, 4,…
## $ deswgt03 <dbl> NA, 3, 1, 3, 4, 5, 4, NA, 4, 3, 3, 4, 4, 4, 4, 3, 4, 3, 5, N…
## $ deswgt05 <dbl> NA, 4, 4, 3, 4, 5, 4, 2, 4, 3, 3, 4, NA, 4, 5, NA, 4, 3, NA,…
## $ deswgt06 <dbl> NA, 4, 5, 3, 4, 5, 4, NA, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, N…
## $ deswgt07 <dbl> NA, 3, 5, 3, 5, 5, 4, NA, 4, 3, 4, 3, NA, 4, 5, NA, 4, 3, 5,…
## $ deswgt08 <dbl> NA, 3, 5, 3, 5, 5, NA, NA, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, …
## $ deswgt09 <dbl> NA, 4, 5, 3, 4, 5, NA, 3, 4, 3, 4, 3, 4, 3, 4, 3, 4, 3, 5, 4…
## $ drkdays97 <dbl> 0, 0, NA, 0, NA, 0, NA, 0, 0, NA, NA, NA, 0, 1, 0, NA, NA, N…
## $ drkdays98 <dbl> NA, NA, 3, 30, 3, 0, 6, 12, NA, NA, 2, NA, 10, 0, 8, 1, 14, …
## $ drkdays01 <dbl> NA, NA, 0, 20, 2, 3, 10, NA, 2, NA, 4, NA, 0, 0, 2, NA, 0, 5…
## $ drkdays02 <dbl> NA, NA, 6, 8, 4, 1, 3, NA, 0, 2, 3, NA, NA, 0, 0, NA, NA, 10…
## $ drkdays03 <dbl> NA, NA, 3, 5, 15, 3, 5, NA, NA, 0, 5, 0, 10, NA, 0, NA, NA, …
## $ drkdays04 <dbl> NA, NA, 0, 5, 10, 5, 4, NA, NA, 3, 7, 0, 10, 1, 0, NA, 7, 1,…
## $ drkdays05 <dbl> NA, NA, 2, 15, 15, 10, 5, 0, NA, 1, 4, NA, NA, NA, 5, NA, NA…
## $ drkdays06 <dbl> NA, NA, 2, 15, 8, 5, 3, NA, 0, 1, 5, 4, 0, 1, 1, 2, 0, 1, 0,…
## $ drkdays07 <dbl> NA, NA, 4, 25, 20, 4, 6, NA, 0, 0, 5, 6, NA, NA, 1, NA, NA, …
## $ drkdays08 <dbl> NA, NA, 4, 20, 27, 5, NA, NA, 0, NA, 5, 6, 1, 0, 0, NA, 6, 0…
## $ drkdays09 <dbl> NA, NA, 2, 15, 5, 4, NA, 0, NA, 7, 9, 7, 10, 1, 4, NA, 4, NA…
## $ male <dbl+lbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ victim00 <dbl> NA, 0, 0, 10, 50, 0, 10, NA, NA, 30, 10, 0, 0, 10, 50, NA, 0…
## $ col30_97 <dbl> 100, 75, 100, 100, 50, 0, 100, 50, 60, 100, 100, 100, 0, 50,…
<-
nlsy.long.data %>%
nlsy.data select(id, bmi01:bmi09) %>%
pivot_longer(cols = bmi01:bmi09,
names_to = "year",
values_to = "bmi") %>%
drop_na() %>%
mutate(year = str_remove(year, "bmi"),
year = as.numeric(year),
year = factor(year,
levels = c(1:9),
labels = c("20", "21", "22", "23", "24", "25", "26",
"27", "28")))
<- lm(bmi ~ year, data = nlsy.long.data)
lm.model
<-
nlsy.long.data %>%
nlsy.long.data mutate(y_hat = predict(lm.model))
ggplot(data = nlsy.long.data %>% sample_n(10),
mapping = aes(x = year, y = bmi, color = id)) +
geom_line()
library(lme4)
## Loading required package: Matrix
##
## Attaching package: 'Matrix'
## The following objects are masked from 'package:tidyr':
##
## expand, pack, unpack
<- lmer(bmi ~ (1 | id), data = nlsy.long.data)
mlm.model ::icc(mlm.model) performance
## # Intraclass Correlation Coefficient
##
## Adjusted ICC: 0.822
## Conditional ICC: 0.822
4.3.1 Fitting a latent growth curve model
library(lavaan)
<- '
growth.model b0 =~ 1 * bmi01 + 1 * bmi02 + 1 * bmi03 + 1 * bmi05 + 1 * bmi06 + 1 * bmi07 +
1 * bmi08
b1 =~ 0 * bmi01 + 1 * bmi02 + 2 * bmi03 + 4 * bmi05 + 5 * bmi06 + 6 * bmi07 +
7 * bmi08 + 8 * bmi09
'
<- growth(growth.model, data = nlsy.data, estimator = "MLMV")
growth.fit summary(growth.fit)
## lavaan 0.6-9 ended normally after 97 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 13
##
## Used Total
## Number of observations 781 1667
##
## Model Test User Model:
## Standard Robust
## Test Statistic 4179.762 1926.979
## Degrees of freedom 31 31
## P-value (Chi-square) 0.000 0.000
## Scaling correction factor 2.184
## Shift parameter 13.390
## simple second-order correction
##
## Parameter Estimates:
##
## Standard errors Robust.sem
## Information Expected
## Information saturated (h1) model Structured
##
## Latent Variables:
## Estimate Std.Err z-value P(>|z|)
## b0 =~
## bmi01 1.000
## bmi02 1.000
## bmi03 1.000
## bmi05 1.000
## bmi06 1.000
## bmi07 1.000
## bmi08 1.000
## b1 =~
## bmi01 0.000
## bmi02 1.000
## bmi03 2.000
## bmi05 4.000
## bmi06 5.000
## bmi07 6.000
## bmi08 7.000
## bmi09 8.000
##
## Covariances:
## Estimate Std.Err z-value P(>|z|)
## b0 ~~
## b1 0.103 0.183 0.565 0.572
##
## Intercepts:
## Estimate Std.Err z-value P(>|z|)
## .bmi01 0.000
## .bmi02 0.000
## .bmi03 0.000
## .bmi05 0.000
## .bmi06 0.000
## .bmi07 0.000
## .bmi08 0.000
## .bmi09 0.000
## b0 25.391 0.194 130.866 0.000
## b1 0.405 0.020 20.700 0.000
##
## Variances:
## Estimate Std.Err z-value P(>|z|)
## .bmi01 2.017 0.303 6.653 0.000
## .bmi02 3.029 0.432 7.013 0.000
## .bmi03 3.965 0.564 7.032 0.000
## .bmi05 4.333 0.680 6.374 0.000
## .bmi06 7.288 4.012 1.817 0.069
## .bmi07 2.010 0.378 5.324 0.000
## .bmi08 3.211 0.439 7.317 0.000
## .bmi09 660.333 2.627 251.336 0.000
## b0 28.249 2.696 10.479 0.000
## b1 0.236 0.028 8.504 0.000
- the expected gain in BMI is 0.405 points each year
4.3.3 Adding a quadratic latent slope growth factor
<- '
growth.model # latent variables
b0 =~ 1 * bmi01 + 1 * bmi02 + 1 * bmi03 + 1 * bmi05 + 1 * bmi06 + 1 * bmi07 +
1 * bmi08
b1 =~ 0 * bmi01 + 1 * bmi02 + 2 * bmi03 + 4 * bmi05 + 5 * bmi06 + 6 * bmi07 +
7 * bmi08 + 8 * bmi09
# residual correlations
bmi01 ~~ bmi02
bmi02 ~~ bmi03
bmi05 ~~ bmi06
bmi06 ~~ bmi07
bmi07 ~~ bmi08
'
<- growth(growth.model, data = nlsy.data, estimator = "MLMV")
growth.fit summary(growth.fit, fit.measures = TRUE)
## lavaan 0.6-9 ended normally after 142 iterations
##
## Estimator ML
## Optimization method NLMINB
## Number of model parameters 18
##
## Used Total
## Number of observations 781 1667
##
## Model Test User Model:
## Standard Robust
## Test Statistic 4113.101 2518.226
## Degrees of freedom 26 26
## P-value (Chi-square) 0.000 0.000
## Scaling correction factor 1.639
## Shift parameter 9.284
## simple second-order correction
##
## Model Test Baseline Model:
##
## Test statistic 10602.030 478.517
## Degrees of freedom 28 28
## P-value 0.000 0.000
## Scaling correction factor 23.241
##
## User Model versus Baseline Model:
##
## Comparative Fit Index (CFI) 0.613 0.000
## Tucker-Lewis Index (TLI) 0.584 -4.957
##
## Robust Comparative Fit Index (CFI) NA
## Robust Tucker-Lewis Index (TLI) NA
##
## Loglikelihood and Information Criteria:
##
## Loglikelihood user model (H0) -16937.991 -16937.991
## Loglikelihood unrestricted model (H1) -14881.441 -14881.441
##
## Akaike (AIC) 33911.982 33911.982
## Bayesian (BIC) 33995.873 33995.873
## Sample-size adjusted Bayesian (BIC) 33938.714 33938.714
##
## Root Mean Square Error of Approximation:
##
## RMSEA 0.449 0.350
## 90 Percent confidence interval - lower 0.437 0.339
## 90 Percent confidence interval - upper 0.460 0.362
## P-value RMSEA <= 0.05 0.000 0.000
##
## Robust RMSEA NA
## 90 Percent confidence interval - lower NA
## 90 Percent confidence interval - upper NA
##
## Standardized Root Mean Square Residual:
##
## SRMR 2.352 2.352
##
## Parameter Estimates:
##
## Standard errors Robust.sem
## Information Expected
## Information saturated (h1) model Structured
##
## Latent Variables:
## Estimate Std.Err z-value P(>|z|)
## b0 =~
## bmi01 1.000
## bmi02 1.000
## bmi03 1.000
## bmi05 1.000
## bmi06 1.000
## bmi07 1.000
## bmi08 1.000
## b1 =~
## bmi01 0.000
## bmi02 1.000
## bmi03 2.000
## bmi05 4.000
## bmi06 5.000
## bmi07 6.000
## bmi08 7.000
## bmi09 8.000
##
## Covariances:
## Estimate Std.Err z-value P(>|z|)
## .bmi01 ~~
## .bmi02 1.007 0.501 2.009 0.045
## .bmi02 ~~
## .bmi03 1.109 0.332 3.339 0.001
## .bmi05 ~~
## .bmi06 0.683 0.244 2.804 0.005
## .bmi06 ~~
## .bmi07 0.643 0.249 2.577 0.010
## .bmi07 ~~
## .bmi08 0.587 0.456 1.287 0.198
## b0 ~~
## b1 0.272 0.208 1.307 0.191
##
## Intercepts:
## Estimate Std.Err z-value P(>|z|)
## .bmi01 0.000
## .bmi02 0.000
## .bmi03 0.000
## .bmi05 0.000
## .bmi06 0.000
## .bmi07 0.000
## .bmi08 0.000
## .bmi09 0.000
## b0 25.331 0.193 131.441 0.000
## b1 0.419 0.019 21.701 0.000
##
## Variances:
## Estimate Std.Err z-value P(>|z|)
## .bmi01 2.471 0.608 4.062 0.000
## .bmi02 4.352 0.668 6.518 0.000
## .bmi03 4.183 0.727 5.756 0.000
## .bmi05 4.193 0.697 6.020 0.000
## .bmi06 7.660 3.969 1.930 0.054
## .bmi07 2.653 0.438 6.056 0.000
## .bmi08 3.509 0.716 4.899 0.000
## .bmi09 652.620 2.376 274.628 0.000
## b0 27.223 2.741 9.932 0.000
## b1 0.199 0.036 5.485 0.000