The goal of moderator analysis in metaSEM::wls()
My understanding is that moderator analysis at the 2nd stage of metaSEM approach using `metaSEM::wls()` involves multi-group analysis.
Thus, as a user I have to `subset` my data by categories of my moderator, and fit the **same model syntax** to each subset as shown below.
But at the end, how can I conclude whether I have a significant moderator or not? For example, should/can I do: `anova(wls1, wls2)` and if one model is significantly different from another conclude that the moderator is significant? (I appreciate a demonstration.)
library(metaSEM)
## Sample sizes
n1 <- 100
n2 <- 200
## Variable labels
vars <- c("y", "x1", "x2")
## Group 1 data and model
R1 <- matrix(c(1.00, 0.22, 0.24,
0.22, 1.00, 0.30,
0.24, 0.30, 1.00), ncol=3, nrow=3,
dimnames=list(vars, vars))
acov1 <- asyCov(R1, n1)
model1 <- "y ~ b1a*x1 + b2a*x2
## Variances of x1 and x2 are 1
x1 ~~ 1*x1
x2 ~~ 1*x2
## x1 and x2 are correlated
x1 ~~ ra*x2"
RAM1 <- lavaan2RAM(model1, obs.variables=vars)
wls1 <- wls(model="Group1", Cov=R1, aCov=acov1, n=n1, RAM=RAM1)
## Group 2 data and model
R2 <- matrix(c(1.00, 0.33, 0.41,
0.33, 1.00, 0.35,
0.41, 0.35, 1.00), ncol=3, nrow=3,
dimnames=list(vars, vars))
acov2 <- asyCov(R2, n2)
model2 <- "y ~ b1b*x1 + b2b*x2
## Variances of x1 and x2 are 1
x1 ~~ 1*x1
x2 ~~ 1*x2
## x1 and x2 are correlated
x1 ~~ rb*x2"
RAM2 <- lavaan2RAM(model2, obs.variables=vars)
wls2 <- wls(model="Group2", Cov=R2, aCov=acov2, n=n2, RAM=RAM2)
wls() was not decided for
Log in or register to post comments
In reply to wls() was not decided for by Mike Cheung
Dear Mike,
Sure, but I asked this to clarify your comment [**HERE**](https://openmx.ssri.psu.edu/comment/9874#comment-9874). In [that comment](https://openmx.ssri.psu.edu/comment/9874#comment-9874), what is the purpose behind creating a combined model like: `mxModel(model="combined", wls1, wls2, mxFitFunctionMultigroup(c("Group1", "Group2")))`? What do the statistics of this combined model tell us about the moderatory role of `"Group"`?
In fact, as I ask in this thread, if the path models are exactly the same across two subsets of data, and we fit `wls(...,run=F)` for each model, then is it possible to compare the two models using `mxModel(..., mxFitFunctionMultigroup(...))` and then `mxRun()`? I really appreciate a demonstration.
Log in or register to post comments
The purpose is to conduct a
The models with equality constraints and without equality constraints are nested. Thus, a chi-square difference statistic can be used to compare them.
There are plenty of resources for subgroup analysis in meta-analysis and multiple-group SEM. Here are some materials for a three-day workshop in MASEM. https://github.com/mikewlcheung/masemWorkshop2023
Log in or register to post comments
In reply to The purpose is to conduct a by Mike Cheung
Dear Mike,
Is it possible to conduct *pairwise comparisons* between the elements of A.matrix and S.matrix from the two groups in the object `output` below?
## Sample sizes
n1 <- 100
n2 <- 200
## Variable labels
vars <- c("y", "x1", "x2")
## Group 1 data and model
R1 <- matrix(c(1.00, 0.22, 0.24,
0.22, 1.00, 0.30,
0.24, 0.30, 1.00), ncol=3, nrow=3,
dimnames=list(vars, vars))
acov1 <- asyCov(R1, n1)
model1 <- "y ~ b1a*x1 + b2a*x2
## Variances of x1 and x2 are 1
x1 ~~ 1*x1
x2 ~~ 1*x2
## x1 and x2 are correlated
x1 ~~ ra*x2"
## Group 2 data but model is the same as model1
R2 <- matrix(c(1.00, 0.33, 0.41,
0.33, 1.00, 0.35,
0.41, 0.35, 1.00), ncol=3, nrow=3,
dimnames=list(vars, vars))
acov2 <- asyCov(R2, n2)
model2 <- "y ~ b1b*x1 + b2b*x2
## Variances of x1 and x2 are 1
x1 ~~ 1*x1
x2 ~~ 1*x2
## x1 and x2 are correlated
x1 ~~ rb*x2"
RAM1 <- lavaan2RAM(model1, obs.variables=vars)
RAM2 <- lavaan2RAM(model2, obs.variables=vars)
wls1 <- wls(model="Group1", Cov=R1, aCov=acov1, n=n1, RAM=RAM1, run=F)
wls2 <- wls(model="Group2", Cov=R2, aCov=acov2, n=n2, RAM=RAM2, run=F)
## Combine both groups
wls.model <- mxModel(model="combined", wls1, wls2, mxFitFunctionMultigroup(c("Group1", "Group2")))
wls.fit <- mxRun(wls.model, intervals=TRUE)
zz = summary(wls.fit)
(output = cbind(zz$parameters[-c(3:4,7:10)], zz$CI[c("lbound","ubound")]))
name matrix Estimate Std.Error lbound ubound
1 b1a Group1.Amatrix 0.1626374 0.09928458 -0.034465926 0.3598924
2 b2a Group1.Amatrix 0.1912088 0.09881592 -0.004306087 0.3874504
3 ra Group1.S1 0.3000000 0.09100000 0.120857208 0.4785835
4 b1b Group2.Amatrix 0.2125356 0.06601287 0.082020597 0.3433026
5 b2b Group2.Amatrix 0.3356125 0.06395664 0.209506797 0.4626121
6 rb Group2.S1 0.3500000 0.06204862 0.228300669 0.4720198
Log in or register to post comments
Yes, but it is not automatic.
You may test the constraints one by one, e.g., b1a=b1b, b2a=b2b. Please note that it does not adjust the issue of multiple comparisons.
Log in or register to post comments
In reply to Yes, but it is not automatic. by Mike Cheung
Thank you, Mike. Can you
Log in or register to post comments
Here is an example.
model1 <- "y ~ b1*x1 + b2a*x2
## Variances of x1 and x2 are 1
x1 ~~ 1*x1
x2 ~~ 1*x2
## x1 and x2 are correlated
x1 ~~ ra*x2"
model2 <- "y ~ b1*x1 + b2b*x2
## Variances of x1 and x2 are 1
x1 ~~ 1*x1
x2 ~~ 1*x2
## x1 and x2 are correlated
x1 ~~ rb*x2"
RAM1 <- lavaan2RAM(model1, obs.variables=vars)
RAM2 <- lavaan2RAM(model2, obs.variables=vars)
wls1 <- wls(model="Group1", Cov=R1, aCov=acov1, n=n1, RAM=RAM1, run=F)
wls2 <- wls(model="Group2", Cov=R2, aCov=acov2, n=n2, RAM=RAM2, run=F)
## Combine both groups
wls.b1 <- mxModel(model="b1", wls1, wls2, mxFitFunctionMultigroup(c("Group1", "Group2")))
fit.b1 <- mxRun(wls.b1, intervals=TRUE)
summary(fit.b1)
anova(wls.fit, fit.b1)
Log in or register to post comments
In reply to Here is an example. by Mike Cheung
Truly appreciated, Mike. Just
If yes, then H0: b1a - b1b = 0, may be tested with standard wald-type, Z-test.
Log in or register to post comments
Yes, you can choose between
Log in or register to post comments
Final confirmation, can Wald
Also, are there any references (papers, book chapters etc.) discussing the use of Wald tests in the manner that I suggested in my previous post for comparing across the estimates from independent groups?
Log in or register to post comments
Wald test can be applied to
You may refer to the literature of multiple group SEM.
Log in or register to post comments
Dear Mike,
Is there any way to convert a `wls()` object with `run=TRUE` or `run=FALSE` to a corresponding lavaan object?
Log in or register to post comments
I am afraid not because this
Log in or register to post comments
All correlations meta-analysis
Hi,
I am new with MetaSEM. I am trying to fit a simple meta-analysis (I just want to analyse 2 correlations; see attached file).
Here you can find the code that I am using with some simulated data but if there are no regressions I cannot make it work. It should be an easy model but I am stuck. I just want two covariances and I have fixed all the variances to one.
Correlations between S and D, S and I and D and I are stored here:
rSD <- c(0.85, 0.8, 0.90, 0.78, 0.70,NA,NA,NA,NA,NA)
rSI <- c(NA,NA,NA,NA,NA,0.85,NA,NA,NA,NA)
rDI <- c(NA,NA,NA,NA,NA,0.60, 0.50, 0.55, 0.60, 0.55)
rSI could be al NAs since I am not interested in that correlation.
Any help and guidance would be really appreciated.
library(metaSEM)
source("http://www.suzannejak.nl/MASEM_functions.R")
rSD <- c(0.85, 0.8, 0.90, 0.78, 0.70,NA,NA,NA,NA,NA)
rSI <- c(NA,NA,NA,NA,NA,0.85,NA,NA,NA,NA)
rDI <- c(NA,NA,NA,NA,NA,0.60, 0.50, 0.55, 0.60, 0.55)
N <- c(10000,40000, 30000, 10000, 10000,20000,10000, 50000, 10000, 10000 )
data <- as.data.frame(cbind(rSD,rSI,rSI, N))
nvar <- 3
varnames <- c("S","D", "I")
labels <- list(varnames,varnames)
cormatrices <- readstack(data[,c(2,1,3)], no.var = nvar, var.names = varnames, diag = FALSE)
n <- data$N
pattern.na(cormatrices, show.na=F)
pattern.n(cormatrices, n=n)
my.df <- Cor2DataFrame(cormatrices, n, acov = "weighted")
## Specify model using lavaan syntax
model <-
'
# Covariances
D ~~ I
D ~~ S
# Variances
D ~~ 1*D
S ~~ 1*S
I ~~ 1*I
'
RAM1 <- lavaan2RAM(model, obs.variables=varnames)
RAM1
## Create the model implied correlation structure with implicit diagonal constraints
M0 <- create.vechsR(A0=RAM1$A, S0=RAM1$S)
## Create the heterogeneity variance-covariance matrix
T0 <- create.Tau2(RAM=RAM1, RE.type="Diag", Transform="expLog", RE.startvalues=0.05)
## Fit the model
mx.fit0 <- osmasem(model.name="No moderator", Mmatrix=M0, Tmatrix=T0, data=my.df)
## View the results
summary(mx.fit0, fitIndices = TRUE)
VarCorr(mx.fit0)
Log in or register to post comments
Hi Juan, I answered your…
Hi Juan,
I answered your question here:
r - All correlations meta-analysis - Cross Validated (stackexchange.com)
Log in or register to post comments