You are here

Estimating means and variances in latent growth curve model

7 posts / 0 new
Last post
dadrivr's picture
Offline
Joined: 01/19/2010 - 23:28
Estimating means and variances in latent growth curve model

In your latent growth curve model example (https://openmx.ssri.psu.edu/docs/OpenMx/latest/TimeSeries_Path.html), you suggest:
-freely estimating the means and variances of the latent intercept and slope factors
-constraining the means of the manifest variables to be zero (to make their means dependent on the intercept and slope means)
-constraining the residual variances of the manifest variables to be equal over time

I am trying to fit a latent growth curve model with three manifest variables at each time point that compose a time-varying latent factor, let's say T1-T6. The latent factors (T1-T6) are then regressed on the latent intercept and slope factors as in your example.

My question is: what should I do with the means and variances of the manifest variables and the latent (T1-T6) variables?

My guess would be to:
-freely estimate the means and variances of the latent intercept and slope factors
-constrain the means of the manifest and T1-T6 latent factors to be zero (to make their means dependent on the intercept and slope)
-constrain the residual variances of the same manifest variable to be equal across time (to fix a given manifest variable's loading across time)
-constrain the residual variance of the latent factors (T1-T6) to be equal across time (for measurement invariance)

Is this right, or would you recommend another approach? Thanks for your help!

Ryne's picture
Offline
Joined: 07/31/2009 - 15:12
You're on the right track. I

You're on the right track. I would:
-freely estimate the means and variances for the intercepts and slopes.
-fix the latent (T1-T6) means to zero and variances to equality across time (freely estimate a single latent residual variance)
-estimate a unique residual for each manifest variable that is invariant across time (if you have variables w, x, y and z, you'll estimate four residual variances that are constrained to equality across all 6 occasions).
-fix the intercept/mean of ONE manifest variable to zero, and estimate the rest, also constraining to equality.

The main difference is the intercepts for the manifest variables. We expect the means of the T1-T6 latent factors to be dependent on the latent interecept and slopes, and the manifest means to depend on the T1-T6 latent factors. However, it is certainly possible that the manifest variables are scaled differently. We give the T1-T6 latent variables a mean by constraining one variable's mean to be zero; constraining all manifest means to be zero would indicate that when someone has a score of "zero" on the factor, they show zeros on all manifest variables as well. Only one manifest mean needs to be set of zero to identify the factor.

An equivalently fitting specification gives all manifest variables a mean (constrained to equality across time) and fixes the intercept factor to have a mean of zero. This is confusing to some people, but if it makes more sense to you, run with it.

dadrivr's picture
Offline
Joined: 01/19/2010 - 23:28
Hi Ryne, That is very

Hi Ryne,

That is very helpful. A couple quick questions to make sure I understand:

  1. Should I fix the mean of one manifest variable to be zero at each time point or one manifest variable to be zero at just one time point?

  2. Should I constrain the mean of all of the other manifest variables (within and across time) to be equal to the one manifest variable (w1=w2=w3=x1=x2=x3=y1=y2=y3), or should I only constrain the mean of the same manifest variable to be invariant across time (w1=w2=w3; x1=x2=x3; y1=y2=y3).

Thanks again!

Ryne's picture
Offline
Joined: 07/31/2009 - 15:12
1. At all timepoints, and, 2.
  1. At all timepoints, and,
  2. The second one. You'll have (variables-1) different means.

All parameters for the first-level factor analysis should be invariant across time, and the model should be identified in such a way that the factor has a mean.

dadrivr's picture
Offline
Joined: 01/19/2010 - 23:28
Hi Ryne, Great, that makes

Hi Ryne,

Great, that makes sense. I just ran a preliminary model, and everything seems to run fine. The only thing I'm concerned about is that the variance for the latent factor (T1-T6) is negative. Is this a problem? If so, do you have any suggestions to address it? I tried fixing the variance to zero in a comparison model, but the model fit is significantly worse, so I'm not sure what to try.

Thanks.

-Isaac

Ryne's picture
Offline
Joined: 07/31/2009 - 15:12
Can you post code? What are

Can you post code? What are the results if you scrap the growth curve and just have factors at all six occasions with no latent variance restrictions, free means and all possible covariances between latent factors?

dadrivr's picture
Offline
Joined: 01/19/2010 - 23:28
Below is code from my working

Below is code from my working model (modified from the original proposed model in my original post):

growthCurveModel <- mxModel("Latent Growth Curve model",
type="RAM",
mxData(
task,
type="raw"
),
manifestVars=c("m1ext","m2ext","m3ext","m4ext","m5ext","m6ext","m7ext","m8ext","m9ext",
"t1ext","t2ext","t3ext","t4ext","t5ext","t6ext","t7ext","t8ext","t9ext"),
latentVars=c("intercept","slope",
"EXT1","EXT2","EXT3","EXT4","EXT5","EXT6","EXT7","EXT8","EXT9"),

# manifest residual variances
mxPath(
    from=c("m1ext","m2ext","m3ext","m4ext","m5ext","m6ext","m7ext","m8ext","m9ext",
      "t1ext","t2ext","t3ext","t4ext","t5ext","t6ext","t7ext","t8ext","t9ext"),
    arrows=2,
    free=TRUE,
    values = 1,
    labels=c("varExtM","varExtM","varExtM","varExtM","varExtM",
      "varExtM","varExtM","varExtM","varExtM",
      "varExtT","varExtT","varExtT","varExtT","varExtT",
      "varExtT","varExtT","varExtT","varExtT")
),

# latent var estimation
mxPath(
    from="EXT1",
    to=c("m1ext","t1ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm1","EXTt1")
),
mxPath(
    from="EXT2",
    to=c("m2ext","t2ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm2","EXTt2")
),
mxPath(
    from="EXT3",
    to=c("m3ext","t3ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm3","EXTt3")
),
mxPath(
    from="EXT4",
    to=c("m4ext","t4ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm4","EXTt4")
),
mxPath(
    from="EXT5",
    to=c("m5ext","t5ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm5","EXTt5")
),
mxPath(
    from="EXT6",
    to=c("m6ext","t6ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm6","EXTt6")
),
mxPath(
    from="EXT7",
    to=c("m7ext","t7ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm7","EXTt7")
),
mxPath(
    from="EXT8",
    to=c("m8ext","t8ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm8","EXTt8")
),
mxPath(
    from="EXT9",
    to=c("m9ext","t9ext"),
    arrows=1,
    free=c(TRUE,FALSE),
    values=c(1, 1),
    labels=c("EXTm9","EXTt9")
),

# intercept/slope variances and covariance
mxPath(
    from=c("intercept","slope"),
    arrows=2,
    all=TRUE,
    free=TRUE,
    values=c(1, 1, 1, 1),
    labels=c("varIntercept", "covInterceptSlope", "covInterceptSlope", "varSlope")
),

# latent variances
mxPath(
    from=c("EXT1","EXT2","EXT3","EXT4","EXT5","EXT6","EXT7","EXT8","EXT9"),
    arrows=2,
    free=TRUE,
    values=1,
    labels="varEXT"
),

# intercept loadings
mxPath(
    from="intercept",
    to=c("EXT1","EXT2","EXT3","EXT4","EXT5","EXT6","EXT7","EXT8","EXT9"),
    arrows=1,
    free=FALSE,
    values=1
),

# slope loadings
mxPath(
    from="slope",
    to=c("EXT1","EXT2","EXT3","EXT4","EXT5","EXT6","EXT7","EXT8","EXT9"),
    arrows=1,
    free=FALSE,
    values=c(0, 1, 2, 3, 4, 5, 6, 7, 8)
),

# manifest means
mxPath(
    from="one",
    to=c("m1ext","m2ext","m3ext","m4ext","m5ext","m6ext","m7ext","m8ext","m9ext"),
    arrows=1,
    free=FALSE,
    values=0,
    labels="meanEXTm"
),
mxPath(
    from="one",
    to=c("t1ext","t2ext","t3ext","t4ext","t5ext","t6ext","t7ext","t8ext","t9ext"),
    arrows=1,
    free=TRUE,
    values=0,
    labels="meanEXTt"
),

# intercept and slope means
mxPath(
    from="one",
    to=c("intercept","slope"),
    arrows=1,
    free=TRUE,
    values=1,
    labels=c("meanIntercept","meanSlope")
),

# latent means
mxPath(
    from="one",
    to=c("EXT1","EXT2","EXT3","EXT4","EXT5","EXT6","EXT7","EXT8","EXT9"),
    arrows=1,
    free=FALSE,
    values=0,
    labels="meanEXT"
)

)

Here's output from the model:
free parameters:
name matrix row col Estimate Std.Error
1 EXTm1 A m1ext EXT1 1.13987303 0.04975978
2 EXTm2 A m2ext EXT2 1.06874272 0.04445574
3 EXTm3 A m3ext EXT3 1.01298291 0.04163771
4 EXTm4 A m4ext EXT4 1.00504151 0.04095812
5 EXTm5 A m5ext EXT5 0.96978067 0.04028366
6 EXTm6 A m6ext EXT6 0.94144638 0.03967146
7 EXTm7 A m7ext EXT7 0.90341247 0.03849427
8 EXTm8 A m8ext EXT8 0.95363863 0.04140362
9 EXTm9 A m9ext EXT9 0.91372075 0.04140311
10 varExtM S m1ext m1ext 26.62588256 1.04659275
11 varExtT S t1ext t1ext 77.68364719 1.86709582
12 varIntercept S intercept intercept 25.70692547 2.44269022
13 covInterceptSlope S intercept slope -0.10766091 0.21379715
14 varSlope S slope slope 0.37568997 0.04553245
15 varEXT S EXT1 EXT1 -7.78175522 0.89321605
16 meanEXTt M 1 t1ext -2.86055675 0.38849551
17 meanIntercept M 1 intercept 9.53088947 0.43950158
18 meanSlope M 1 slope 0.04392185 0.05042719

observed statistics: 8464
estimated parameters: 18
degrees of freedom: 8446
-2 log likelihood: 56449.07
saturated -2 log likelihood: NA
number of observations: 585
chi-square: NA
p: NA
AIC (Mx): 39557.07
BIC (Mx): 1317.218
adjusted BIC:
RMSEA: NA
timestamp: 2011-02-25 17:06:23
frontend time: 1.626 secs
backend time: 52.312 secs
independent submodels time: 0 secs
wall clock time: 53.938 secs
cpu time: 53.938 secs
openmx version number: 1.0.4-1540

Below is the output from the model with no latent variance restrictions, free means, and all possible covariances between latent variables. I had to change the number of iterations to 2000 in order to get it to converge.

free parameters:
name matrix row col Estimate Std.Error
1 EXTm1 A m1ext EXT1 0.8831181 0.09278456
2 EXTm2 A m2ext EXT2 0.9315233 0.07629018
3 EXTm3 A m3ext EXT3 0.8249190 0.06637018
4 EXTm4 A m4ext EXT4 1.0479375 0.08426017
5 EXTm5 A m5ext EXT5 0.8829892 0.06466705
6 EXTm6 A m6ext EXT6 0.9854213 0.07054715
7 EXTm7 A m7ext EXT7 1.1649515 0.10899530
8 EXTm8 A m8ext EXT8 1.2919792 0.11862418
9 EXTm9 A m9ext EXT9 0.9859418 0.09385699
10 varExtM S m1ext m1ext 27.9005199 1.03016420
11 varExtT S t1ext t1ext 78.1658213 1.88907227
12 S EXT1 EXT1 19.5999893 3.38624547
13 S EXT1 EXT2 30.9673399 3.63824787
14 S EXT2 EXT2 21.6522209 3.33560927
15 S EXT1 EXT3 32.4872888 3.98270583
16 S EXT2 EXT3 36.4961037 3.81156442
17 S EXT3 EXT3 28.0254055 4.54959013
18 S EXT1 EXT4 28.4336243 3.51360382
19 S EXT2 EXT4 32.0068066 3.39879175
20 S EXT3 EXT4 38.3186737 4.35483732
21 S EXT4 EXT4 24.3989711 3.94746939
22 S EXT1 EXT5 29.6388125 3.41269424
23 S EXT2 EXT5 34.0704499 3.27957758
24 S EXT3 EXT5 38.6316190 3.87745489
25 S EXT4 EXT5 37.9170940 3.93362212
26 S EXT5 EXT5 29.5760323 4.05743139
27 S EXT1 EXT6 27.9776530 3.17599273
28 S EXT2 EXT6 31.4942457 2.79225317
29 S EXT3 EXT6 37.7491646 3.63763110
30 S EXT4 EXT6 33.3740915 3.27466897
31 S EXT5 EXT6 40.1266907 3.42740197
32 S EXT6 EXT6 25.8787471 3.46103149
33 S EXT1 EXT7 21.4062465 2.83658927
34 S EXT2 EXT7 25.3962128 2.81230977
35 S EXT3 EXT7 28.0864916 3.30272634
36 S EXT4 EXT7 27.8958757 3.33907513
37 S EXT5 EXT7 31.5934431 3.42379684
38 S EXT6 EXT7 30.8606129 3.19011016
39 S EXT7 EXT7 18.1455552 3.48598502
40 S EXT1 EXT8 20.5898702 2.55688675
41 S EXT2 EXT8 22.3602206 2.27005854
42 S EXT3 EXT8 25.9121497 2.85286676
43 S EXT4 EXT8 25.4100401 2.83457794
44 S EXT5 EXT8 30.3250842 2.99530873
45 S EXT6 EXT8 29.2163206 2.79435122
46 S EXT7 EXT8 25.5409457 3.11543467
47 S EXT8 EXT8 16.5240039 2.96130598
48 S EXT1 EXT9 23.9573724 3.23365447
49 S EXT2 EXT9 28.0991295 3.23627173
50 S EXT3 EXT9 31.5064802 3.84778075
51 S EXT4 EXT9 32.5075670 3.93019890
52 S EXT5 EXT9 37.9600966 4.06754484
53 S EXT6 EXT9 33.0929526 3.53912701
54 S EXT7 EXT9 27.7544191 3.46672730
55 S EXT8 EXT9 30.6950678 3.65848019
56 S EXT9 EXT9 32.2778922 6.05112289
57 meanEXTm1 M 1 m1ext 7.8340310 NaN
58 meanEXTm2 M 1 m2ext 3.0403834 1.56618377
59 meanEXTm3 M 1 m3ext 1.8372538 NaN
60 meanEXTm4 M 1 m4ext -31.0318984 NaN
61 meanEXTm5 M 1 m5ext 37.9093124 22.86435367
62 meanEXTm6 M 1 m6ext -3.2874809 2.46724920
63 meanEXTm7 M 1 m7ext 25.8882752 NaN
64 meanEXTm8 M 1 m8ext -12.2828849 NaN
65 meanEXTm9 M 1 m9ext 22.2326120 NaN
66 meanEXTt1 M 1 t1ext 1.5915611 NaN
67 meanEXTt2 M 1 t2ext -1.1056273 1.38217920
68 meanEXTt3 M 1 t3ext -2.4497468 NaN
69 meanEXTt4 M 1 t4ext -31.9414093 NaN
70 meanEXTt5 M 1 t5ext 39.0605748 26.32042894
71 meanEXTt6 M 1 t6ext -4.9617488 3.31787637
72 meanEXTt7 M 1 t7ext 21.9441108 NaN
73 meanEXTt8 M 1 t8ext -9.8636589 NaN
74 meanEXTt9 M 1 t9ext 21.1108858 NaN
75 meanEXT1 M 1 EXT1 4.1295303 NaN
76 meanEXT2 M 1 EXT2 7.7020986 1.44682444
77 meanEXT3 M 1 EXT3 9.5343680 NaN
78 meanEXT4 M 1 EXT4 38.4904906 NaN
79 meanEXT5 M 1 EXT5 -32.5208717 26.30980582
80 meanEXT6 M 1 EXT6 12.2394346 3.35479645
81 meanEXT7 M 1 EXT7 -14.6769294 NaN
82 meanEXT8 M 1 EXT8 16.7551223 NaN
83 meanEXT9 M 1 EXT9 -13.1074546 NaN

observed statistics: 8464
estimated parameters: 83
degrees of freedom: 8381
-2 log likelihood: 56186.54
saturated -2 log likelihood: NA
number of observations: 585
chi-square: NA
p: NA
AIC (Mx): 39424.54
BIC (Mx): 1393.028
adjusted BIC:
RMSEA: NA
timestamp: 2011-03-01 09:28:03
frontend time: 2.751 secs
backend time: 38.61945 mins
independent submodels time: 0 secs
wall clock time: 2319.918 secs
cpu time: 2319.918 secs
openmx version number: 1.0.4-1540