milanwiedemann / lcsm

An R package for latent change score modelling (LCSM)
https://milanwiedemann.github.io/lcsm/
Other
17 stars 3 forks source link

add function to specify multiple indicators for each latent true score #1

Open milanwiedemann opened 5 years ago

milanwiedemann commented 5 years ago

see this paper for ideas and code published on osf Kievit, R. A., Brandmaier, A. M., Ziegler, G., van Harmelen, A.-L., de Mooij, S. M. M., Moutoussis, M., … Dolan, R. J. (2018). Developmental cognitive neuroscience using latent change score models: A tutorial and applications. Developmental Cognitive Neuroscience, 33, 99–117. https://doi.org/10.1016/j.dcn.2017.11.007

milanwiedemann commented 5 years ago

something like this could work for specifying the the construct "a" with two indicators (items here, i = item) at each time point (t = time) in the variable argument, the functions used to generate the code would then go through each of these lists

list("a_t1" = list("a_t1_i1", "a_t1_i1"), "a2" = list("a_t2_i1", "a_t2_i1"))

AliceeDiaz commented 3 years ago

Hi! I am just trying out lcsm for the first time (I am no expert in R either). I was wondering if you had tried to introduce certain specifications for bivariate models using specify_bi_lcsm and then using lavaan's function. I have tried to just get the syntax for a simple model:

_cat(specify_bi_lcsm( timepoints=2, var_x= "x", model_x = list(alpha_constant = TRUE, beta = TRUE, phi = FALSE), var_y="y", model_y = list(alpha_constant = TRUE, beta = TRUE, phi = FALSE), coupling= list(xi_lag_yx=TRUE), # Change score x predicting subsequent change score y change_letter_x = "g", change_lettery = "j" ))

I have put this output into "model_2" and then, I have tried to fit the model using:

_sem(model_2, data=data_unilcsm, missing = "ml")

The error I get is:

_Error in lav_datafull(data = data, group = group, cluster = cluster, : lavaan ERROR: missing observed variables in dataset: y1 y2 dy3 dx1

So I guess that maybe lavaan does not know how to read/compute certain parameters that are built into lcsm, but it would be great if this was not the case, and you could point me into the right direction!

Thanks so much for your time! Alice

(I am running this with R Version 1.1.463; using Macintosh; Intel Mac OS X 10_13_6 )

milanwiedemann commented 3 years ago

I haven't added multiple indicators for latent true scores yet, but I'm also not sure if you're referring to this issue?

In your example it looks like you're getting an error running a bivariate latent change score model. I tried running the code you posted and can see two reasons why it's not working:

  1. is simply because the example data set data_uni_lcsm only has values for one repeated construct (x1 to x10). the model you specified is a bivariate model that also expects variables named y1 and y2. changing it to data = data_bi_lcsm should work
  2. another problem seems to be that you are trying to estimate whether changes in x at time t are predicting subsequent changes in y at time t+1 (xi_lag_yx = TRUE). at the beginning of your model you only specified two time points timepoints = 2. with only 2 time points the lagged change to change parameter can't be estimated, at least 3 time points (timepoints = 3) would need to be specified.

I've changed the code slightly to show how it could work but I'm not sure whether this is what you're interested in?

# Load packages
library(lcsm)
library(lavaan)

# Specify bivariate lavaan syntax
model_syntax_2 <- specify_bi_lcsm(
  timepoints = 3,
  var_x = "x",
  model_x = list(alpha_constant = TRUE, 
                 beta = TRUE, 
                 phi = FALSE),
  var_y = "y",
  model_y = list(alpha_constant = TRUE, 
                 beta = TRUE, 
                 phi = FALSE),
  coupling = list(xi_lag_yx = TRUE), # Change score x predicting subsequent change score y
  change_letter_x = "g",
  change_letter_y = "j")

# Run model in lavaan
model_2 <- sem(model = model_syntax_2, 
               data = data_bi_lcsm, 
               missing = "ml")

# Extract fit statistics and parameter estimates
extract_fit(model_2)
extract_param(model_2)

let me know if this doesn't answer your question. there would also be another ways to estimate this model using the function fit_bi_lcsm(). I'm also planning to update the readme file on github soon with some more helpful examples.

AliceeDiaz commented 3 years ago

Hi, thanks for your promt response!

Ugh, I am sorry I bother you with such a stupid mistake, did not realize I was loading the univariate data in the bivariate model.

I think I understand the issue with the waves. I have two variables measured in three waves. By now, I just wanted to look at how the change in variable x from T1 to T2 affected change of variable y from T2 to T3. It does make sense to specify 3 waves because the package will automatically only use T1 and T2 for x and T2- T3 for y. Sorry I did not realized about this before...

Thanks again!

milanwiedemann commented 3 years ago

No worries, I still need to write more helpful error messages that make it easier to understand why things don't work! Glad to hear things are clearer now, let me know if you get stuck or funny error messages show up again!

dseclab commented 6 months ago

something like this could work for specifying the the construct "a" with two indicators (items here, i = item) at each time point (t = time) in the variable argument, the functions used to generate the code would then go through each of these lists

list("a_t1" = list("a_t1_i1", "a_t1_i1"), "a2" = list("a_t2_i1", "a_t2_i1"))

Hello! I was wondering whether it was possible to make latent constructs out of multiple observed variables using the lcsm package syntax. I tried the above suggestion as follows:

fit_uni_lcsm(data = abcdwide, var = c("T0_Rsupramarg" = list("T0_tfmri_nback_all_504", "T0_tfmri_nback_all_538"), "T1_Rsupramarg" = list("T1_tfmri_nback_all_504", "T1_tfmri_nback_all_538"), "T2_Rsupramarg" = list("T2_tfmri_nback_all_504", "T2_tfmri_nback_all_538")), model = list(alpha_constant = TRUE, beta = TRUE, phi = TRUE))

... where I am trying to create a latent construct 'T0_Rsupramarg' out of the observed variables 'T0_tfmri_nback_all_504' and 'T0_tfmri_nback_all_538', a latent construct 'T1_Rsupramarg' out of the observed variables 'T1_tfmri_nback_all_504' and 'T1_tfmri_nback_all_538', and a latent construct 'T2_Rsupramarg' out of the observed variables 'T2_tfmri_nback_all_504' and 'T2_tfmri_nback_all_538' (as Time 0, Time 1, and Time 2 latent construct , respectively).

This doesn't seem to work, as it seems to create 6 latent variables instead. Do you have a suggestion? Or am I thinking about this in the wrong way?

Thank you in advance (and thank you for this package!! It is amazing!), Michele