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)
nlsy.data <- read_dta("bmiworking.dta")

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.model <- lm(bmi ~ year, data = nlsy.long.data)

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
mlm.model <- lmer(bmi ~ (1 | id), data = nlsy.long.data)
performance::icc(mlm.model)
## # 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.fit <- growth(growth.model, data = nlsy.data, estimator = "MLMV")
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.2 Adding correlated adjacent error terms

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.fit <- growth(growth.model, data = nlsy.data, estimator = "MLMV")
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

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.fit <- growth(growth.model, data = nlsy.data, estimator = "MLMV")
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

4.4 How can we add time-invariant covariates to our model?