My last post demonstrated a dual change model for one variable, now I want to demonstrate a bivariate dual change model. A SEM path diagram for a bivariate dual change model is below, taken from Wang, Zhou, and Zhang (2016)

(If you do not have access to that link you can view a similar path diagram in Jones, King, Gilrane, McCausland, Cortina, & Grimm, 2016)

Essentially, we have two dual change processes and a coupling parameter from the latent true score on one variable to the latent change score on the other.

The DGP

\[\begin{equation} y_t = constant_y + (1 + proportion_y)*y_{t-1} + coupling_{xy}*x_{t-1} + e \end{equation}\]

where \(constant_y\) is the change factor (or latent slope) on \(y\), \(proportion_y\) is the proportion change factor, and \(coupling_xy\) is the coupling parameter relating \(x\) to \(y\). The DGP for \(x\) is

\[\begin{equation} x_t = constant_x + (1 + proportion_x)*x_{t-1} + coupling_{yx}*y_{t-1} + e \end{equation}\]

where the terms are similar but now applied to values of \(x\). The true values used in the DGP are:

\[\begin{align} y_t &= 0.5 + (1 + -0.32)y_{t-1} + 0.4x_{t-1} + e \\ x_t &= 0.5 + (1 + 0.22)x_{t-1} - 0.4y_{t-1} + e \end{align}\]

with initial values for both \(x\) and \(y\) sampled from \(N\) ~ (10, 1).

people <- 700
time <- 6
x_cause_y <- 0.4
y_cause_x <- -0.4

const_x <- 0.5
const_y <- 0.5

prop_x <- 0.22
prop_y <- -0.32

df_mat <- matrix(, ncol = 4, nrow = people*time)
count <- 0

for(i in 1:people){
  
  unob_het_y <- rnorm(1, 0, 3)
  unob_het_x <- rnorm(1, 0, 3)
  
  for(j in 1:time){
    count <- count + 1
    
    if(j == 1){
      df_mat[count, 1] <- i
      df_mat[count, 2] <- j
      df_mat[count, 3] <- rnorm(1, 10, 1)
      df_mat[count, 4] <- rnorm(1, 10, 1)
    }else{
      
      df_mat[count, 1] <- i
      df_mat[count, 2] <- j
      df_mat[count, 3] <- const_x + (1+prop_x)*df_mat[count - 1, 3] + y_cause_x*df_mat[count - 1, 4] + unob_het_x + rnorm(1,0,1)
      df_mat[count, 4] <- const_y + (1+prop_y)*df_mat[count - 1, 4] + x_cause_y*df_mat[count - 1, 3] + unob_het_y + rnorm(1,0,1)
    }
    
  }
  
  
}

library(tidyverse)
library(ggplot2)
library(reshape2)

df <- data.frame(df_mat)
names(df) <- c('id', 'time', 'x', 'y')

Values of \(y\) over time.

random_nums <- sample(c(1:700), 6)
df_sample <- df %>%
  filter(id %in% random_nums)

ggplot(df, aes(x = time, y = y, group = id)) + 
  geom_point(color = 'grey85') + 
  geom_line(color = 'grey85') + 
  geom_point(data = df_sample, aes(x = time, y = y, group = id)) + 
  geom_line(data = df_sample, aes(x = time, y = y, group = id))

Values of \(x\) over time.

plot_single_response <- function(y_axis){
  
  plot_it <- ggplot(df, aes(x = time, y = !!y_axis, group = id)) + 
    geom_point(color = 'grey85') + 
    geom_line(color = 'grey85') + 
    geom_point(data = df_sample, aes(x = time, y = !!y_axis, group = id)) + 
    geom_line(data = df_sample, aes(x = time, y = !!y_axis, group = id))
  
  return(plot_it)
}

plot_single_response(quo(x))

Three randomly selected individuals with \(x\) and \(y\) plotted simultaneously.

three_cases <- df %>%
  filter(id == 4 | id == 500 | id == 322) %>%
  gather(x, y, key = 'variable', value = 'response')

ggplot(three_cases, aes(x = time, y = response, color = variable)) + 
  geom_point() + 
  geom_line() + 
  facet_wrap(~id)

Dual Change Model on Y

df_wide_y <- df %>%
  select(id, time, y) %>%
  reshape(idvar = 'id', timevar = 'time', direction = 'wide')

library(lavaan)

dual_change_y_string <- '

# latent true scores over y
ly1 =~ 1*y.1
ly2 =~ 1*y.2
ly3 =~ 1*y.3
ly4 =~ 1*y.4
ly5 =~ 1*y.5
ly6 =~ 1*y.6

# latent change scores over the true scores (but not the first time point)
cy2 =~ 1*ly2
cy3 =~ 1*ly3
cy4 =~ 1*ly4
cy5 =~ 1*ly5
cy6 =~ 1*ly6

# autoregressions of latent true scores over y constrained to 1
ly2 ~ 1*ly1
ly3 ~ 1*ly2
ly4 ~ 1*ly3
ly5 ~ 1*ly4
ly6 ~ 1*ly5

# latent intercept over first latent true score on y
l_intercept =~ 1*ly1

# change component 1 of the dual change model

# latent slope (or change factor) over the change scores
l_slope =~ 1*cy2 + 1*cy3 + 1*cy4 + 1*cy5 + 1*cy6

# estimate means and variances of those intercept and slope terms
l_intercept ~~ l_intercept
l_slope ~~ l_slope
l_slope ~ 1
l_intercept ~ 1

# and a covariance between them
l_intercept ~~ l_slope

# change component 2 of the dual change model

# proportion change from true scores over y to the change factors
cy2 ~ prop*ly1
cy3 ~ prop*ly2
cy4 ~ prop*ly3
cy5 ~ prop*ly4
cy6 ~ prop*ly5

# means and variances of latent factors set to zero
ly1 ~ 0
ly2 ~ 0
ly3 ~ 0
ly4 ~ 0
ly5 ~ 0
ly6 ~ 0

cy2 ~ 0
cy3 ~ 0
cy4 ~ 0
cy5 ~ 0
cy6 ~ 0

ly1 ~~ 0*ly1
ly2 ~~ 0*ly2
ly3 ~~ 0*ly3
ly4 ~~ 0*ly4
ly5 ~~ 0*ly5
ly6 ~~ 0*ly6

cy2 ~~ 0*cy2
cy3 ~~ 0*cy3
cy4 ~~ 0*cy4
cy5 ~~ 0*cy5
cy6 ~~ 0*cy6

# means of indicators to zero
y.1 ~ 0
y.2 ~ 0
y.3 ~ 0
y.4 ~ 0
y.5 ~ 0
y.6 ~ 0

# residual variances constrained to equality across time
y.1 ~~ res_var*y.1
y.2 ~~ res_var*y.2
y.3 ~~ res_var*y.3
y.4 ~~ res_var*y.4
y.5 ~~ res_var*y.5
y.6 ~~ res_var*y.6

# do not allow change factors to correlate
cy2 ~~ 0*cy3 + 0*cy4 + 0*cy5 + 0*cy6
cy3 ~~ 0*cy4 + 0*cy5 + 0*cy6
cy4 ~~ 0*cy5 + 0*cy6
cy5 ~~ 0*cy6

'

dc_y_model <- sem(dual_change_y_string, data = df_wide_y)
summary(dc_y_model, fit.measures = T)
## lavaan 0.6-3 ended normally after 70 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         16
##   Number of equality constraints                     9
## 
##   Number of observations                           700
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                    6067.310
##   Degrees of freedom                                20
##   P-value (Chi-square)                           0.000
## 
## Model test baseline model:
## 
##   Minimum Function Test Statistic             7955.551
##   Degrees of freedom                                15
##   P-value                                        0.000
## 
## User model versus baseline model:
## 
##   Comparative Fit Index (CFI)                    0.238
##   Tucker-Lewis Index (TLI)                       0.429
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)             -11519.219
##   Loglikelihood unrestricted model (H1)      -8485.564
## 
##   Number of free parameters                          7
##   Akaike (AIC)                               23052.438
##   Bayesian (BIC)                             23084.296
##   Sample-size adjusted Bayesian (BIC)        23062.069
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.657
##   90 Percent Confidence Interval          0.643  0.671
##   P-value RMSEA <= 0.05                          0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           2.258
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ly1 =~                                              
##     y.1               1.000                           
##   ly2 =~                                              
##     y.2               1.000                           
##   ly3 =~                                              
##     y.3               1.000                           
##   ly4 =~                                              
##     y.4               1.000                           
##   ly5 =~                                              
##     y.5               1.000                           
##   ly6 =~                                              
##     y.6               1.000                           
##   cy2 =~                                              
##     ly2               1.000                           
##   cy3 =~                                              
##     ly3               1.000                           
##   cy4 =~                                              
##     ly4               1.000                           
##   cy5 =~                                              
##     ly5               1.000                           
##   cy6 =~                                              
##     ly6               1.000                           
##   l_intercept =~                                      
##     ly1               1.000                           
##   l_slope =~                                          
##     cy2               1.000                           
##     cy3               1.000                           
##     cy4               1.000                           
##     cy5               1.000                           
##     cy6               1.000                           
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ly2 ~                                               
##     ly1               1.000                           
##   ly3 ~                                               
##     ly2               1.000                           
##   ly4 ~                                               
##     ly3               1.000                           
##   ly5 ~                                               
##     ly4               1.000                           
##   ly6 ~                                               
##     ly5               1.000                           
##   cy2 ~                                               
##     ly1     (prop)    0.313    0.019   16.735    0.000
##   cy3 ~                                               
##     ly2     (prop)    0.313    0.019   16.735    0.000
##   cy4 ~                                               
##     ly3     (prop)    0.313    0.019   16.735    0.000
##   cy5 ~                                               
##     ly4     (prop)    0.313    0.019   16.735    0.000
##   cy6 ~                                               
##     ly5     (prop)    0.313    0.019   16.735    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   l_intercept ~~                                      
##     l_slope          -1.656    0.210   -7.881    0.000
##  .cy2 ~~                                              
##    .cy3               0.000                           
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##  .cy3 ~~                                              
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##  .cy4 ~~                                              
##    .cy5               0.000                           
##    .cy6               0.000                           
##  .cy5 ~~                                              
##    .cy6               0.000                           
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     l_slope          -3.976    0.207  -19.164    0.000
##     l_intercept      11.536    0.107  107.690    0.000
##     ly1               0.000                           
##    .ly2               0.000                           
##    .ly3               0.000                           
##    .ly4               0.000                           
##    .ly5               0.000                           
##    .ly6               0.000                           
##    .cy2               0.000                           
##    .cy3               0.000                           
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##    .y.1               0.000                           
##    .y.2               0.000                           
##    .y.3               0.000                           
##    .y.4               0.000                           
##    .y.5               0.000                           
##    .y.6               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     l_ntrcp           5.263    0.427   12.341    0.000
##     l_slope           2.069    0.171   12.095    0.000
##     ly1               0.000                           
##    .ly2               0.000                           
##    .ly3               0.000                           
##    .ly4               0.000                           
##    .ly5               0.000                           
##    .ly6               0.000                           
##    .cy2               0.000                           
##    .cy3               0.000                           
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##    .y.1     (rs_v)    6.411    0.171   37.417    0.000
##    .y.2     (rs_v)    6.411    0.171   37.417    0.000
##    .y.3     (rs_v)    6.411    0.171   37.417    0.000
##    .y.4     (rs_v)    6.411    0.171   37.417    0.000
##    .y.5     (rs_v)    6.411    0.171   37.417    0.000
##    .y.6     (rs_v)    6.411    0.171   37.417    0.000

Code to change the \(y\)’s in the string to \(x\)’s without manually deleting and inserting \(x\) into the string above. All you have to do is paste the string into a .txt document and save the file as “y_file.txt”

library(readr)

mystring <- read_file('y_file.txt')
new_data <- gsub('y', 'x', mystring)
# write_file(new_data, path = 'x_file.txt') # not executed but will work

Dual Change Model on X

df_wide_x <- df %>%
  select(id, time, x) %>%
  reshape(idvar = 'id', timevar = 'time', direction = 'wide')


library(lavaan)

dual_change_x_string <- '

# latent true scores over x
lx1 =~ 1*x.1
lx2 =~ 1*x.2
lx3 =~ 1*x.3
lx4 =~ 1*x.4
lx5 =~ 1*x.5
lx6 =~ 1*x.6

# latent change scores over the true scores (but not the first time point)
cx2 =~ 1*lx2
cx3 =~ 1*lx3
cx4 =~ 1*lx4
cx5 =~ 1*lx5
cx6 =~ 1*lx6

# autoregressions of latent true scores over x constrained to 1
lx2 ~ 1*lx1
lx3 ~ 1*lx2
lx4 ~ 1*lx3
lx5 ~ 1*lx4
lx6 ~ 1*lx5

# latent intercept over first latent true score on x
l_intercept =~ 1*lx1

# change component 1 of the dual change model

# latent slope (or change factor) over the change scores
l_slope =~ 1*cx2 + 1*cx3 + 1*cx4 + 1*cx5 + 1*cx6

# estimate means and variances of those intercept and slope terms
l_intercept ~~ l_intercept
l_slope ~~ l_slope
l_slope ~ 1
l_intercept ~ 1

# and a covariance between them
l_intercept ~~ l_slope

# change component 2 of the dual change model

# proportion change from true scores over x to the change factors
cx2 ~ prop*lx1
cx3 ~ prop*lx2
cx4 ~ prop*lx3
cx5 ~ prop*lx4
cx6 ~ prop*lx5

# means and variances of latent factors set to zero
lx1 ~ 0
lx2 ~ 0
lx3 ~ 0
lx4 ~ 0
lx5 ~ 0
lx6 ~ 0

cx2 ~ 0
cx3 ~ 0
cx4 ~ 0
cx5 ~ 0
cx6 ~ 0

lx1 ~~ 0*lx1
lx2 ~~ 0*lx2
lx3 ~~ 0*lx3
lx4 ~~ 0*lx4
lx5 ~~ 0*lx5
lx6 ~~ 0*lx6

cx2 ~~ 0*cx2
cx3 ~~ 0*cx3
cx4 ~~ 0*cx4
cx5 ~~ 0*cx5
cx6 ~~ 0*cx6

# means of indicators to zero
x.1 ~ 0
x.2 ~ 0
x.3 ~ 0
x.4 ~ 0
x.5 ~ 0
x.6 ~ 0

# residual variances constrained to equalitx across time
x.1 ~~ res_var*x.1
x.2 ~~ res_var*x.2
x.3 ~~ res_var*x.3
x.4 ~~ res_var*x.4
x.5 ~~ res_var*x.5
x.6 ~~ res_var*x.6

# do not allow change factors to correlate
cx2 ~~ 0*cx3 + 0*cx4 + 0*cx5 + 0*cx6
cx3 ~~ 0*cx4 + 0*cx5 + 0*cx6
cx4 ~~ 0*cx5 + 0*cx6
cx5 ~~ 0*cx6

'

dc_x_model <- sem(dual_change_x_string, data = df_wide_x)
summary(dc_x_model, fit.measures = T)
## lavaan 0.6-3 ended normally after 55 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         16
##   Number of equality constraints                     9
## 
##   Number of observations                           700
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                    4046.134
##   Degrees of freedom                                20
##   P-value (Chi-square)                           0.000
## 
## Model test baseline model:
## 
##   Minimum Function Test Statistic            11769.574
##   Degrees of freedom                                15
##   P-value                                        0.000
## 
## User model versus baseline model:
## 
##   Comparative Fit Index (CFI)                    0.657
##   Tucker-Lewis Index (TLI)                       0.743
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)             -10105.606
##   Loglikelihood unrestricted model (H1)      -8082.539
## 
##   Number of free parameters                          7
##   Akaike (AIC)                               20225.212
##   Bayesian (BIC)                             20257.069
##   Sample-size adjusted Bayesian (BIC)        20234.843
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.536
##   90 Percent Confidence Interval          0.522  0.550
##   P-value RMSEA <= 0.05                          0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.723
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   lx1 =~                                              
##     x.1               1.000                           
##   lx2 =~                                              
##     x.2               1.000                           
##   lx3 =~                                              
##     x.3               1.000                           
##   lx4 =~                                              
##     x.4               1.000                           
##   lx5 =~                                              
##     x.5               1.000                           
##   lx6 =~                                              
##     x.6               1.000                           
##   cx2 =~                                              
##     lx2               1.000                           
##   cx3 =~                                              
##     lx3               1.000                           
##   cx4 =~                                              
##     lx4               1.000                           
##   cx5 =~                                              
##     lx5               1.000                           
##   cx6 =~                                              
##     lx6               1.000                           
##   l_intercept =~                                      
##     lx1               1.000                           
##   l_slope =~                                          
##     cx2               1.000                           
##     cx3               1.000                           
##     cx4               1.000                           
##     cx5               1.000                           
##     cx6               1.000                           
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   lx2 ~                                               
##     lx1               1.000                           
##   lx3 ~                                               
##     lx2               1.000                           
##   lx4 ~                                               
##     lx3               1.000                           
##   lx5 ~                                               
##     lx4               1.000                           
##   lx6 ~                                               
##     lx5               1.000                           
##   cx2 ~                                               
##     lx1     (prop)    0.150    0.004   35.444    0.000
##   cx3 ~                                               
##     lx2     (prop)    0.150    0.004   35.444    0.000
##   cx4 ~                                               
##     lx3     (prop)    0.150    0.004   35.444    0.000
##   cx5 ~                                               
##     lx4     (prop)    0.150    0.004   35.444    0.000
##   cx6 ~                                               
##     lx5     (prop)    0.150    0.004   35.444    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   l_intercept ~~                                      
##     l_slope          -0.928    0.255   -3.641    0.000
##  .cx2 ~~                                              
##    .cx3               0.000                           
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##  .cx3 ~~                                              
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##  .cx4 ~~                                              
##    .cx5               0.000                           
##    .cx6               0.000                           
##  .cx5 ~~                                              
##    .cx6               0.000                           
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     l_slope          -3.468    0.123  -28.161    0.000
##     l_intercept      10.332    0.077  134.910    0.000
##     lx1               0.000                           
##    .lx2               0.000                           
##    .lx3               0.000                           
##    .lx4               0.000                           
##    .lx5               0.000                           
##    .lx6               0.000                           
##    .cx2               0.000                           
##    .cx3               0.000                           
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##    .x.1               0.000                           
##    .x.2               0.000                           
##    .x.3               0.000                           
##    .x.4               0.000                           
##    .x.5               0.000                           
##    .x.6               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     l_ntrcp           2.969    0.212   14.021    0.000
##     l_slope          10.023    0.574   17.467    0.000
##     lx1               0.000                           
##    .lx2               0.000                           
##    .lx3               0.000                           
##    .lx4               0.000                           
##    .lx5               0.000                           
##    .lx6               0.000                           
##    .cx2               0.000                           
##    .cx3               0.000                           
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##    .x.1     (rs_v)    2.088    0.056   37.417    0.000
##    .x.2     (rs_v)    2.088    0.056   37.417    0.000
##    .x.3     (rs_v)    2.088    0.056   37.417    0.000
##    .x.4     (rs_v)    2.088    0.056   37.417    0.000
##    .x.5     (rs_v)    2.088    0.056   37.417    0.000
##    .x.6     (rs_v)    2.088    0.056   37.417    0.000

Bivariate Dual Change Model

bi_dc_string <- '

# DUAL CHANGE IN Y

#

#

#

# latent true scores over y
ly1 =~ 1*y.1
ly2 =~ 1*y.2
ly3 =~ 1*y.3
ly4 =~ 1*y.4
ly5 =~ 1*y.5
ly6 =~ 1*y.6

# latent change scores over the true scores (but not the first time point)
cy2 =~ 1*ly2
cy3 =~ 1*ly3
cy4 =~ 1*ly4
cy5 =~ 1*ly5
cy6 =~ 1*ly6

# autoregressions of latent true scores over y constrained to 1
ly2 ~ 1*ly1
ly3 ~ 1*ly2
ly4 ~ 1*ly3
ly5 ~ 1*ly4
ly6 ~ 1*ly5

# latent intercept over first latent true score on y
l_intercept =~ 1*ly1

# change component 1 of the dual change model

# latent slope (or change factor) over the change scores
l_slope =~ 1*cy2 + 1*cy3 + 1*cy4 + 1*cy5 + 1*cy6

# estimate means and variances of those intercept and slope terms
l_intercept ~~ l_intercept
l_slope ~~ l_slope
l_slope ~ 1
l_intercept ~ 1

# and a covariance between them
l_intercept ~~ l_slope

# change component 2 of the dual change model

# proportion change from true scores over y to the change factors
cy2 ~ prop*ly1
cy3 ~ prop*ly2
cy4 ~ prop*ly3
cy5 ~ prop*ly4
cy6 ~ prop*ly5

# means and variances of latent factors set to zero
ly1 ~ 0
ly2 ~ 0
ly3 ~ 0
ly4 ~ 0
ly5 ~ 0
ly6 ~ 0

cy2 ~ 0
cy3 ~ 0
cy4 ~ 0
cy5 ~ 0
cy6 ~ 0

ly1 ~~ 0*ly1
ly2 ~~ 0*ly2
ly3 ~~ 0*ly3
ly4 ~~ 0*ly4
ly5 ~~ 0*ly5
ly6 ~~ 0*ly6

cy2 ~~ 0*cy2
cy3 ~~ 0*cy3
cy4 ~~ 0*cy4
cy5 ~~ 0*cy5
cy6 ~~ 0*cy6

# means of indicators to zero
y.1 ~ 0
y.2 ~ 0
y.3 ~ 0
y.4 ~ 0
y.5 ~ 0
y.6 ~ 0

# residual variances constrained to equality across time
y.1 ~~ res_var*y.1
y.2 ~~ res_var*y.2
y.3 ~~ res_var*y.3
y.4 ~~ res_var*y.4
y.5 ~~ res_var*y.5
y.6 ~~ res_var*y.6

# do not allow change factors to correlate
cy2 ~~ 0*cy3 + 0*cy4 + 0*cy5 + 0*cy6
cy3 ~~ 0*cy4 + 0*cy5 + 0*cy6
cy4 ~~ 0*cy5 + 0*cy6
cy5 ~~ 0*cy6


# DUAL CHANGE IN X

#

#

#






# latent true scores over x
lx1 =~ 1*x.1
lx2 =~ 1*x.2
lx3 =~ 1*x.3
lx4 =~ 1*x.4
lx5 =~ 1*x.5
lx6 =~ 1*x.6

# latent change scores over the true scores (but not the first time point)
cx2 =~ 1*lx2
cx3 =~ 1*lx3
cx4 =~ 1*lx4
cx5 =~ 1*lx5
cx6 =~ 1*lx6

# autoregressions of latent true scores over x constrained to 1
lx2 ~ 1*lx1
lx3 ~ 1*lx2
lx4 ~ 1*lx3
lx5 ~ 1*lx4
lx6 ~ 1*lx5

# latent intercept over first latent true score on x
lx_intercept =~ 1*lx1

# change component 1 of the dual change model

# latent slope (or change factor) over the change scores
lx_slope =~ 1*cx2 + 1*cx3 + 1*cx4 + 1*cx5 + 1*cx6

# estimate means and variances of those intercept and slope terms
lx_intercept ~~ lx_intercept
lx_slope ~~ lx_slope
lx_slope ~ 1
lx_intercept ~ 1

# and a covariance between them
lx_intercept ~~ lx_slope

# change component 2 of the dual change model

# proportion change from true scores over x to the change factors
cx2 ~ propx*lx1
cx3 ~ propx*lx2
cx4 ~ propx*lx3
cx5 ~ propx*lx4
cx6 ~ propx*lx5

# means and variances of latent factors set to zero
lx1 ~ 0
lx2 ~ 0
lx3 ~ 0
lx4 ~ 0
lx5 ~ 0
lx6 ~ 0

cx2 ~ 0
cx3 ~ 0
cx4 ~ 0
cx5 ~ 0
cx6 ~ 0

lx1 ~~ 0*lx1
lx2 ~~ 0*lx2
lx3 ~~ 0*lx3
lx4 ~~ 0*lx4
lx5 ~~ 0*lx5
lx6 ~~ 0*lx6

cx2 ~~ 0*cx2
cx3 ~~ 0*cx3
cx4 ~~ 0*cx4
cx5 ~~ 0*cx5
cx6 ~~ 0*cx6

# means of indicators to zero
x.1 ~ 0
x.2 ~ 0
x.3 ~ 0
x.4 ~ 0
x.5 ~ 0
x.6 ~ 0

# residual variances constrained to equalitx across time
x.1 ~~ res_varx*x.1
x.2 ~~ res_varx*x.2
x.3 ~~ res_varx*x.3
x.4 ~~ res_varx*x.4
x.5 ~~ res_varx*x.5
x.6 ~~ res_varx*x.6

# do not allow change factors to correlate
cx2 ~~ 0*cx3 + 0*cx4 + 0*cx5 + 0*cx6
cx3 ~~ 0*cx4 + 0*cx5 + 0*cx6
cx4 ~~ 0*cx5 + 0*cx6
cx5 ~~ 0*cx6

# COUPLING

#

#

cy2 ~ xy*lx1
cy3 ~ xy*lx2
cy4 ~ xy*lx3
cy5 ~ xy*lx4
cy6 ~ xy*lx5

cx2 ~ yx*ly1
cx3 ~ yx*ly2
cx4 ~ yx*ly3
cx5 ~ yx*ly4
cx6 ~ yx*ly5


'

df_both <- df %>%
  reshape(idvar = 'id', timevar = 'time', direction = 'wide')

bi_dc_model <- sem(bi_dc_string, data = df_both)
summary(bi_dc_model, fit.measures = T)
## lavaan 0.6-3 ended normally after 117 iterations
## 
##   Optimization method                           NLMINB
##   Number of free parameters                         46
##   Number of equality constraints                    26
## 
##   Number of observations                           700
## 
##   Estimator                                         ML
##   Model Fit Test Statistic                    1422.723
##   Degrees of freedom                                70
##   P-value (Chi-square)                           0.000
## 
## Model test baseline model:
## 
##   Minimum Function Test Statistic            23848.355
##   Degrees of freedom                                66
##   P-value                                        0.000
## 
## User model versus baseline model:
## 
##   Comparative Fit Index (CFI)                    0.943
##   Tucker-Lewis Index (TLI)                       0.946
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)             -15217.849
##   Loglikelihood unrestricted model (H1)     -14506.488
## 
##   Number of free parameters                         20
##   Akaike (AIC)                               30475.699
##   Bayesian (BIC)                             30566.721
##   Sample-size adjusted Bayesian (BIC)        30503.217
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.166
##   90 Percent Confidence Interval          0.159  0.174
##   P-value RMSEA <= 0.05                          0.000
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.098
## 
## Parameter Estimates:
## 
##   Information                                 Expected
##   Information saturated (h1) model          Structured
##   Standard Errors                             Standard
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ly1 =~                                              
##     y.1               1.000                           
##   ly2 =~                                              
##     y.2               1.000                           
##   ly3 =~                                              
##     y.3               1.000                           
##   ly4 =~                                              
##     y.4               1.000                           
##   ly5 =~                                              
##     y.5               1.000                           
##   ly6 =~                                              
##     y.6               1.000                           
##   cy2 =~                                              
##     ly2               1.000                           
##   cy3 =~                                              
##     ly3               1.000                           
##   cy4 =~                                              
##     ly4               1.000                           
##   cy5 =~                                              
##     ly5               1.000                           
##   cy6 =~                                              
##     ly6               1.000                           
##   l_intercept =~                                      
##     ly1               1.000                           
##   l_slope =~                                          
##     cy2               1.000                           
##     cy3               1.000                           
##     cy4               1.000                           
##     cy5               1.000                           
##     cy6               1.000                           
##   lx1 =~                                              
##     x.1               1.000                           
##   lx2 =~                                              
##     x.2               1.000                           
##   lx3 =~                                              
##     x.3               1.000                           
##   lx4 =~                                              
##     x.4               1.000                           
##   lx5 =~                                              
##     x.5               1.000                           
##   lx6 =~                                              
##     x.6               1.000                           
##   cx2 =~                                              
##     lx2               1.000                           
##   cx3 =~                                              
##     lx3               1.000                           
##   cx4 =~                                              
##     lx4               1.000                           
##   cx5 =~                                              
##     lx5               1.000                           
##   cx6 =~                                              
##     lx6               1.000                           
##   lx_intercept =~                                     
##     lx1               1.000                           
##   lx_slope =~                                         
##     cx2               1.000                           
##     cx3               1.000                           
##     cx4               1.000                           
##     cx5               1.000                           
##     cx6               1.000                           
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   ly2 ~                                               
##     ly1               1.000                           
##   ly3 ~                                               
##     ly2               1.000                           
##   ly4 ~                                               
##     ly3               1.000                           
##   ly5 ~                                               
##     ly4               1.000                           
##   ly6 ~                                               
##     ly5               1.000                           
##   cy2 ~                                               
##     ly1     (prop)   -0.315    0.004  -74.218    0.000
##   cy3 ~                                               
##     ly2     (prop)   -0.315    0.004  -74.218    0.000
##   cy4 ~                                               
##     ly3     (prop)   -0.315    0.004  -74.218    0.000
##   cy5 ~                                               
##     ly4     (prop)   -0.315    0.004  -74.218    0.000
##   cy6 ~                                               
##     ly5     (prop)   -0.315    0.004  -74.218    0.000
##   lx2 ~                                               
##     lx1               1.000                           
##   lx3 ~                                               
##     lx2               1.000                           
##   lx4 ~                                               
##     lx3               1.000                           
##   lx5 ~                                               
##     lx4               1.000                           
##   lx6 ~                                               
##     lx5               1.000                           
##   cx2 ~                                               
##     lx1     (prpx)    0.225    0.002  101.044    0.000
##   cx3 ~                                               
##     lx2     (prpx)    0.225    0.002  101.044    0.000
##   cx4 ~                                               
##     lx3     (prpx)    0.225    0.002  101.044    0.000
##   cx5 ~                                               
##     lx4     (prpx)    0.225    0.002  101.044    0.000
##   cx6 ~                                               
##     lx5     (prpx)    0.225    0.002  101.044    0.000
##   cy2 ~                                               
##     lx1       (xy)    0.403    0.002  184.708    0.000
##   cy3 ~                                               
##     lx2       (xy)    0.403    0.002  184.708    0.000
##   cy4 ~                                               
##     lx3       (xy)    0.403    0.002  184.708    0.000
##   cy5 ~                                               
##     lx4       (xy)    0.403    0.002  184.708    0.000
##   cy6 ~                                               
##     lx5       (xy)    0.403    0.002  184.708    0.000
##   cx2 ~                                               
##     ly1       (yx)   -0.420    0.004  -96.376    0.000
##   cx3 ~                                               
##     ly2       (yx)   -0.420    0.004  -96.376    0.000
##   cx4 ~                                               
##     ly3       (yx)   -0.420    0.004  -96.376    0.000
##   cx5 ~                                               
##     ly4       (yx)   -0.420    0.004  -96.376    0.000
##   cx6 ~                                               
##     ly5       (yx)   -0.420    0.004  -96.376    0.000
## 
## Covariances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##   l_intercept ~~                                      
##     l_slope          -0.134    0.136   -0.985    0.324
##  .cy2 ~~                                              
##    .cy3               0.000                           
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##  .cy3 ~~                                              
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##  .cy4 ~~                                              
##    .cy5               0.000                           
##    .cy6               0.000                           
##  .cy5 ~~                                              
##    .cy6               0.000                           
##   lx_intercept ~~                                     
##     lx_slope         -0.033    0.135   -0.244    0.807
##  .cx2 ~~                                              
##    .cx3               0.000                           
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##  .cx3 ~~                                              
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##  .cx4 ~~                                              
##    .cx5               0.000                           
##    .cx6               0.000                           
##  .cx5 ~~                                              
##    .cx6               0.000                           
##   l_intercept ~~                                      
##     lx_intercept     -0.130    0.051   -2.526    0.012
##     lx_slope          0.001    0.140    0.009    0.993
##   l_slope ~~                                          
##     lx_intercept     -0.051    0.131   -0.393    0.695
##     lx_slope          0.213    0.336    0.635    0.526
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     l_slope           0.466    0.117    3.994    0.000
##     l_intercept       9.983    0.045  220.323    0.000
##     ly1               0.000                           
##    .ly2               0.000                           
##    .ly3               0.000                           
##    .ly4               0.000                           
##    .ly5               0.000                           
##    .ly6               0.000                           
##    .cy2               0.000                           
##    .cy3               0.000                           
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##    .y.1               0.000                           
##    .y.2               0.000                           
##    .y.3               0.000                           
##    .y.4               0.000                           
##    .y.5               0.000                           
##    .y.6               0.000                           
##     lx_slope          0.664    0.122    5.441    0.000
##     lx_intercept      9.937    0.044  224.982    0.000
##     lx1               0.000                           
##    .lx2               0.000                           
##    .lx3               0.000                           
##    .lx4               0.000                           
##    .lx5               0.000                           
##    .lx6               0.000                           
##    .cx2               0.000                           
##    .cx3               0.000                           
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##    .x.1               0.000                           
##    .x.2               0.000                           
##    .x.3               0.000                           
##    .x.4               0.000                           
##    .x.5               0.000                           
##    .x.6               0.000                           
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)
##     l_ntr             0.965    0.075   12.954    0.000
##     l_slp             8.201    0.454   18.047    0.000
##     ly1               0.000                           
##    .ly2               0.000                           
##    .ly3               0.000                           
##    .ly4               0.000                           
##    .ly5               0.000                           
##    .ly6               0.000                           
##    .cy2               0.000                           
##    .cy3               0.000                           
##    .cy4               0.000                           
##    .cy5               0.000                           
##    .cy6               0.000                           
##    .y.1   (res_vr)    0.726    0.019   37.348    0.000
##    .y.2   (res_vr)    0.726    0.019   37.348    0.000
##    .y.3   (res_vr)    0.726    0.019   37.348    0.000
##    .y.4   (res_vr)    0.726    0.019   37.348    0.000
##    .y.5   (res_vr)    0.726    0.019   37.348    0.000
##    .y.6   (res_vr)    0.726    0.019   37.348    0.000
##     lx_nt             1.140    0.071   16.062    0.000
##     lx_sl             9.056    0.494   18.318    0.000
##     lx1               0.000                           
##    .lx2               0.000                           
##    .lx3               0.000                           
##    .lx4               0.000                           
##    .lx5               0.000                           
##    .lx6               0.000                           
##    .cx2               0.000                           
##    .cx3               0.000                           
##    .cx4               0.000                           
##    .cx5               0.000                           
##    .cx6               0.000                           
##    .x.1   (rs_vrx)    0.417    0.011   36.461    0.000
##    .x.2   (rs_vrx)    0.417    0.011   36.461    0.000
##    .x.3   (rs_vrx)    0.417    0.011   36.461    0.000
##    .x.4   (rs_vrx)    0.417    0.011   36.461    0.000
##    .x.5   (rs_vrx)    0.417    0.011   36.461    0.000
##    .x.6   (rs_vrx)    0.417    0.011   36.461    0.000

Bo\(^2\)m =)