Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Multilevel BSEM

63 views
Skip to first unread message

HeeDong Yoon

unread,
Sep 10, 2024, 8:59:00 AM9/10/24
to blavaan
Hi all,

Currently, I am teaching myself how to use blavaan and have encountered several questions regarding the multilevel SEM in blavaan.

First, this is a brief introduction of how my experiment was conducted. In my experiment, each participant completed multiple trials. For each trial, I collected their time_estimation, interest, and attention responses. Prior to the experiment, each participant conducted a quiz and a survey. Based on these quiz and survey scores, they were categorized into groups (group 1 or group 2).

A proportion of my data is shown in the mydata.png.
My goal is to examine the role of encoding and event_boundary on time_estimation, but here I want to include the random effects of participant and group.
From what I learned so far, I can put "participant" for cluster because I have multiple data points (rows) per participant. However, I also expect the data from participants of different groups (1 or 2) to differ. How can I apply this in my code? Since there are only one quiz and survey scores for each participant, I put them in the second level (i.e, between).
Below is the code I have so far:

# SEM model
time_model <- '
level: within
# Latent Variables
encoding =~ interest + attention
# Regression
time_estimation ~ time_encoding + event_boundary
level: between
# Latent Variables
encoding =~ interest + attention
world_knowledge =~ quiz + survey
# Regression
time_estimation ~ encoding + event_boundary + world_knowledge
'

# Fit the model using blavaan
time_model_fit <- bsem(time_model,
data = mydata,
cluster = "participant",
burnin = 1000,
sample = 2000,
n.chains = 4,
dp = time_model_priors
)

I am new to this, so any suggestions on the model or on the multilevel SEM in general is appreciated.

Thanks in advance. 
mydata.png

Ed Merkle

unread,
Sep 10, 2024, 3:09:11 PM9/10/24
to HeeDong Yoon, blavaan

HeeDong,

Welcome! If there are two groups of unique participants, I would think to model them as separate groups instead of as random effects. In this case, it is possible to use the "group" argument along with the "cluster" argument:

cluster = "participant", group = "group"

Now you will have two sets of estimates, one for group 1 and one for group 2. You could constrain some parameters to be equal across groups, or you could obtain posterior intervals of the differences between parameters across groups. The latter could be facilitated by extracting the posterior samples from the fitted model:

samps <- do.call("rbind", blavInspect(fit, "mcmc"))

Ed


On Mon, 2024-09-09 at 23:41 -0700, HeeDong Yoon wrote:

Hi all,
>
Currently, I am teaching myself how to use blavaan and have
> encountered several questions regarding the multilevel SEM in
> blavaan.
>
First, this is a brief introduction of how my experiment was
> conducted. In my experiment, each participant completed multiple
> trials. For each trial, I collected their time_estimation, interest,
> and attention responses. Prior to the experiment, each participant
> conducted a quiz and a survey. Based on these quiz and survey scores,
> they were categorized into groups (group 1 or group 2).
>
A proportion of my data is shown in the mydata.png.

> My goal is to examine the role of encoding and event_boundary on
> time_estimation, but here I want to include the random effects of
> participant and group.
> From what I learned so far, I can put "participant" for cluster
> because I have multiple data points (rows) per participant. However,
> I also expect the data from participants of different groups (1 or 2)
> to differ. How can I apply this in my code? Since there are only one
> quiz and survey scores for each participant, I put them in the second
> level (i.e, between).
> Below is the code I have so far:
>

SEM model
>

time_model <- '
>  level: within
>  # Latent Variables
>  encoding =~ interest + attention
>  # Regression
>  time_estimation ~ time_encoding + event_boundary
>  level: between
>  # Latent Variables
>  encoding =~ interest + attention
>  world_knowledge =~ quiz + survey
>  # Regression
>  time_estimation ~ encoding + event_boundary + world_knowledge
> '
>

Fit the model using blavaan
>

time_model_fit <- bsem(time_model,
>  data = mydata,
>  cluster = "participant",
>  burnin = 1000,
>  sample = 2000,
>  n.chains = 4,
>  dp = time_model_priors
>  )
>
I am new to this, so any suggestions on the model or on the
> multilevel SEM in general is appreciated.
>
Thanks in advance. 

> --
> You received this message because you are subscribed to the Google
> Groups "blavaan" group.
> To unsubscribe from this group and stop receiving emails from it,
> send an email to blavaan+u...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/blavaan/7f5e131d-5c0f-4142-b8ce-45f144b250efn%40googlegroups.com.


Terrence Jorgensen

unread,
Sep 11, 2024, 6:08:44 AM9/11/24
to blavaan

it is possible to use the "group" argument along with the "cluster" argument:

cluster = "participant", group = "group"

I assume the model syntax must also specify how levels are nested in the (Level-2) groups, as it would when fitting a multigroup MLSEM in lavaan.


Terrence D. Jorgensen    (he, him, his)
Assistant Professor, Methods and Statistics
Research Institute for Child Development and Education, the University of Amsterdam
http://www.uva.nl/profile/t.d.jorgensen


Ed Merkle

unread,
Sep 11, 2024, 9:45:32 AM9/11/24
to Terrence Jorgensen, blavaan
Yes, good point! You also need the "group: " lines in the model syntax, as shown in Terrence's link.

Ed
--
You received this message because you are subscribed to the Google Groups "blavaan" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blavaan+u...@googlegroups.com.

HeeDong Yoon

unread,
Sep 12, 2024, 11:23:21 PM9/12/24
to blavaan
ED and Terrence, 

Thank you both very much for providing such a clear solution! I was able to use cluster = "participant,"  group = "group" as well as "group:" in the model syntax. 

I'm currently exploring a few additional aspects of the model to ensure everything is configured as intended. I'll reach out again if I encounter any further issues.

Thank you!  

2024년 9월 11일 수요일 오후 10시 45분 32초 UTC+9에 Ed Merkle님이 작성:

HeeDong Yoon

unread,
Oct 2, 2024, 7:25:00 AM10/2/24
to blavaan
Hi all, 

I came across several other questions while I was working with bsem. 

1. Is there a way to extract estimates for individual participants rather than averaged values?

My dataset consists of repeated measures from multiple participants. I am hoping to access each participant's estimates for each variable.

# My code: 
time_model_fit <- bsem(time_model,
                                           data = mydata,
                                           cluster = "participant",
                                           group = "group",
                                           burnin = 2000,  
                                           sample = 4000,  
                                           n.chains = 4,
                                            dp = time_model_priors,
                                            seed = 1234
                                            )

summary(time_model_fit,
                  standardized = TRUE,
                  fit.measures = TRUE
                  )

2. When I summarize the model using the summary function, I get a PPP value of 0, which I believe represents a poor model fit. 

I am not sure how to interpret this result, and if needed, how I can improve my model syntax?

Please feel free to advise or correct me if I am doing something wrong.



2024년 9월 13일 금요일 오후 12시 23분 21초 UTC+9에 HeeDong Yoon님이 작성:
Message has been deleted

Ed Merkle

unread,
Oct 3, 2024, 1:31:35 PM10/3/24
to HeeDong Yoon, blavaan
HeeDong,

For your #1, I believe you are wanting the person latent variables. To do that, add

save.lvs = TRUE

to your bsem() command. Then, after you fit the model, you should be able to obtain the person latent variables via

lvs <- blavInspect(time_model_fit, "lvmeans", level = 2)

You could also obtain the posterior samples (instead of posterior means) for each person, by replacing "lvmeans" with "lvs".


For your #2, yes, a ppp of 0 provides some evidence of poor fit. There is no general-purpose way to obtain a better model. I would start with scatteplots of observed variables, to help ensure the data look as expected. Then I might consider fitting a separate model to each participant, to see whether certain participants have especially good or bad fit. Then maybe also fit pieces of the model separately (say, each latent variable) to see whether certain pieces have good or bad fit.

Ed

Mauricio Garnier-Villarreal

unread,
Oct 4, 2024, 12:14:19 PM10/4/24
to blavaan
HeeDong

This is larger issue, how to evaluate model fit Multilevel BSEM?

For now, we have develop ways toe evaluate model fit in BSEM with continuous indicators https://psycnet.apa.org/doiLanding?doi=10.1037%2Fmet0000224

But have not develop the equivalemnt method for Multilevel BSEM yet. As you can see in that paper, we do not recommend to rely on the PPP for model fit, as it has similar issues as the p-value from the chi-square in frequentist SEM.

You could evaluate the model residuals, like SRMR with the ppmc() function. As way to look at residual model fit. But for now, other approaches are limited

take care
Reply all
Reply to author
Forward
0 new messages