[R-meta] Multivariate meta-analysis - moderator analysis and tau squared
Mika Manninen
m|xu89 @end|ng |rom gm@||@com
Thu Sep 24 19:45:02 CEST 2020
Hello,
I am doing a meta-analysis looking at the effect of a teaching intervention
(versus control) on six types of motivation/behavioural regulation.
Theoretically and empirically these constructs form a continuum in which
the continuum neighbours are most strongly positively correlated and the
furthest from one another most negatively correlated.
I received help from Professors Wolfgang Viechtbauer and James Pustejovsky
already in July with the variance-covariance matrix computation. Thank you
again!
Now with all data collected, I have a few additional questions.regarding.
1. Warning message "positive definite"
2. Getting Q and I squared values from a multivariate meta-analysis output
3. and 4.Interpreting moderator analysis with categorical moderators
(Egger-type test, too for publication bias)
5. Suggestion for reporting forest plot and funnel plot for this type of
analysis (137 effects and 37 studies in the original datafile).
A subsample of data and relevant analyses can be done with the code
provided below. The aforementioned questions are blended into the text to
make answering them easier.
__________
#Install metafor package before proceeding with meta-analysis
library("metafor", lib.loc="~/R/R-4.0.0/library")
#Create the dataframe (without covariance matrix)
meta <- structure(list(Author = c("Abula et al., 2018", "Abula et al.,
2018",
"Abula et al., 2018", "Abula et al., 2018",
"Abula et al., 2018",
"Barkoukis et al., 2020", "Barkoukis et al.,
2020", "Barkoukis et al., 2020",
"Barkoukis et al., 2020", "Behzadnia et al.,
2017", "Behzadnia et al., 2017",
"Behzadnia et al., 2017", "Behzadnia et al.,
2017", "Chang et al., 2016",
"Chang et al., 2016", "Chang et al., 2016",
"Chang et al., 2016",
"Chang et al., 2016", "Cheon et al., 2010",
"Cheon et al., 2010",
"Cheon et al., 2010", "Cheon et al., 2010",
"Cheon et al., 2010",
"Cheon et al., 2012", "Cheon et al., 2015",
"Cheon et al., 2016",
"Edmunds et al., 2008", "Edmunds et al., 2008",
"Edmunds et al., 2008",
"Edmunds et al., 2008", "Edmunds et al., 2008",
"Edmunds et al., 2008",
"Fin et al., 2019", "Fin et al., 2019", "Fin et
al., 2019", "Fin et al., 2019",
"Fin et al., 2019", "Franco et al., 2017",
"Fransen etal., 2018",
"Gillison et al., 2013", "Gillison et al., 2013",
"Gillison et al., 2013",
"Gillison et al., 2013", "Gillison et al., 2013",
"González-Cutre et al., 2018",
"González-Cutre et al., 2018", "González-Cutre et
al., 2018",
"González-Cutre et al., 2018", "González-Cutre et
al., 2018",
"González-Cutre et al., 2018", "Ha et al., 2019",
"Ha et al., 2019"),
study = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,
4, 4, 5, 5, 5, 5, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9,
10, 10, 10, 10,
10, 11, 12, 13, 13, 13, 13, 13, 14, 14, 14, 14,
14, 14, 15, 15),
outcome = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46,
47, 48, 49, 50, 51, 52),
motivation = c(1, 3, 4, 5, 6, 1, 3, 4, 5, 1, 3, 4, 5, 1, 3, 4, 5, 6, 1, 3,
4, 5, 6, 6, 6, 6, 1, 2,
3, 4, 5, 6, 1, 3, 4, 5, 6, 1, 1, 1, 3, 4, 5,
6, 1, 2, 3, 4, 5,
6, 1, 3),
g = c(0.528464772324917, 0.0589694070444635, 0.282008465683339,
-0.0920405520247558, 0.0404267845152442, 0.419921031000001,
0.288692999072491,
-0.129114905405604, 0.0153234677481859, 1.692130349854,
1.5655112070775,
0.797525006036895, 0.202220243923423, 0.560898338638158,
0.120018930689234,
0.320629566196145, -0.0255557448041566, -0.356052957510261,
0.836181226696161,
0.945619432746331, -1.14695724875324, -0.316929747502631,
-0.444939499881025,
-0.103827982870712, -0.124551198480087, -0.270481778614604,
0.193279463967818,
-0.220165204655694, 0.328515459564001, -0.661405951944594,
-0.0588677781991213,
0.381443142567869, 0.405279105271576, -0.0689560292055143,
-0.406763178319009,
-1.28981574597883, -0.12834586771615, 0.493626759881918,
0.527629708371335,
0.14237493801129, 0.181922479878477, -0.012193145480936,
-0.476411871637917,
-0.239292055322439, 0.135428894231014, -0.140303735152328,
-0.125317079792252,
-0.199539217658822, 0.347519633564979, -0.0569303505457916,
0.0331393420421724,
0.127165941804818),
v = c(0.0126374422978132, 0.0136501896827314,
0.0172092970523336, 0.0158304677686747, 0.015196984404496,
0.0117016875107911,
0.0129905670084342, 0.0160782230295901, 0.0130349120410749,
0.166244292906422,
0.172788985120758, 0.169998384821774, 0.147236242254395,
0.026050596807523,
0.0280225511437046, 0.0353688036495172, 0.0324162425207384,
0.0316517208270417,
0.125246076172345, 0.143299200337245, 0.182870602701095,
0.148364422975138,
0.144468441612776, 0.00274503202263367, 0.00657178221924943,
0.00378625733110702, 0.0567043412519983, 0.0698128695544358,
0.064578154151857, 0.083501070217046, 0.0737350489050993,
0.0721490273295586,
0.0536371594302375, 0.0589692454871346, 0.0750760396309753,
0.0825343404161793,
0.0657659083731156, 0.0622812720119753, 0.0317147286821705,
0.0165661561004418,
0.0186223247379937, 0.023286686815142, 0.0220852914411238,
0.0207926243477567,
0.0402229479672577, 0.0494884645771515, 0.045350892784268,
0.0568053388291199,
0.0531589046798887, 0.0504220144875667, 0.00506476243264833,
0.00572614282481596),
setting = c(0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1,
1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0),
scope = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2, 2,
2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 3, 3, 3,
3, 3, 3, 3, 3),
typei = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0),
typec = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0),
length = c(2, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1),
age = c(1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0),
oq = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2,
1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1, 1, 1, 1),
mqi = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 2, 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1),
tq = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
1, 1, 1, 1)),
row.names = c(NA,-52L), class = c("tbl_df", "tbl", "data.frame"))
View(meta)
corlist <- list(structure(c(1, NA, 0.96, 0.34, -0.33, -0.66, NA, NA, NA,
NA, NA, NA, 0.96, NA, 1, 0.55, -0.12, -0.5, 0.34, NA,
0.55, 1,
0.53, 0.05, -0.33, NA, -0.12, 0.53, 1, 0.72, -0.66, NA,
-0.5,
0.05, 0.72, 1), .Dim = c(6L, 6L)), structure(c(1, NA,
0.374,
0.034,
0.108, NA, NA, NA, NA, NA, NA, NA, 0.374, NA, 1, 0.261,
0.22, NA,
0.034, NA, 0.261, 1, 0.381, NA, 0.108, NA, 0.22, 0.381,
1, NA, NA,
NA, NA, NA, NA, NA), .Dim = c(6L, 6L)), structure(c(1,
NA, 0.96, 0.34, -0.33,
NA, NA, NA, NA, NA, NA, NA, 0.96, NA,
1, 0.55, -0.12, NA,
0.34, NA, 0.55, 1, 0.53, NA, -0.33, NA, -0.12,
0.53, 1, NA, NA, NA, NA,
NA, NA, NA), .Dim = c(6L, 6L)), structure(c(1,
NA, 0.96, 0.34, -0.33, -0.66,
NA, NA, NA, NA, NA, NA, 0.96, NA,
1, 0.55, -0.12, -0.5, 0.34, NA,
0.55, 1, 0.53, 0.05, -0.33, NA,
-0.12, 0.53, 1, 0.72, -0.66,
NA, -0.5, 0.05, 0.72, 1), .Dim = c(6L,
6L)), structure(c(1, NA, 0.85, 0.35, 0.06,
-0.44, NA, NA, NA,
NA, NA, NA, 0.85, NA, 1,
0.59, 0.46, -0.14, 0.35, NA, 0.59, 1,
0.71, 0.27, 0.06, NA,
0.46, 0.71, 1, 0.52, -0.44, NA, -0.14,
0.27, 0.52, 1), .Dim =
c(6L, 6L)), structure(c(NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, 1
), .Dim = c(6L, 6L)),
structure(c(NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 1), .Dim = c(6L,
6L)),
structure(c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, 1), .Dim = c(6L, 6L)),
structure(c(1,
0.79, 0.84, 0.24, -0.2, -0.5, 0.79, 1, 0.93, 0.47, 0, -0.31,
0.84, 0.93, 1, 0.57, -0.07, -0.52, 0.24, 0.47, 0.57, 1, 0.43,
0.01, -0.2, 0, -0.07, 0.43, 1, 0.55, -0.5, -0.31, -0.52, 0.01,
0.55, 1), .Dim = c(6L, 6L)), structure(c(1, NA, 0.96, 0.34, -0.33,
-0.66, NA, NA, NA, NA, NA, NA,
0.96, NA, 1, 0.55, -0.12, -0.5,
0.34, NA, 0.55, 1, 0.53, 0.05,
-0.33, NA, -0.12, 0.53, 1, 0.72,
-0.66, NA, -0.5, 0.05, 0.72, 1),
.Dim = c(6L, 6L)), structure(c(1,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA,
NA, NA, NA), .Dim = c(6L, 6L)),
structure(c(1, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), .Dim = c(6L,
6L)),
structure(c(1, NA, 0.96, 0.34, -0.33, -0.66, NA, NA, NA,
NA, NA, NA, 0.96, NA, 1, 0.55, -0.12, -0.5, 0.34, NA, 0.55, 1,
0.53, 0.05, -0.33, NA, -0.12, 0.53, 1, 0.72, -0.66, NA, -0.5,
0.05, 0.72, 1), .Dim = c(6L, 6L)), structure(c(1, 0.76, 0.96,
0.34, -0.33,
-0.66, 0.76, 1, 0.62, 0.25, -0.09, -0.41, 0.96,
0.62, 1, 0.55,
-0.12, -0.5, 0.34, 0.25, 0.55, 1, 0.53, 0.05,
-0.33, -0.09,
-0.12, 0.53, 1, 0.72, -0.66, -0.41, -0.5, 0.05,
0.72, 1), .Dim =
c(6L, 6L)), structure(c(1, NA, 0.79, NA, NA,
NA, NA, NA, NA, NA, NA, NA, 0.79, NA, 1, NA, NA, NA,
NA, NA,
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
NA, NA, NA
), .Dim = c(6L,
6L)))
# A correlation matrix for the levels of motivation actually observed -
omitting NAs (by W.Viechtbauer, July2020)
mots <- split(meta$motivation, meta$study)
corlist <- mapply(function(rmat, mots) rmat[mots,mots], corlist, mots)
corlist
#Creating the covariance matrix - V-matrix function (w. Viechtbauer, July
2020)
Vfun <- function(vi,rmat) {
if (length(vi) == 1L) {
matrix(vi)
} else {
S <- diag(sqrt(vi))
S %*% rmat %*% S
}
}
V <- mapply(Vfun, split(meta$v, meta$study), corlist)
V
#Here I sometimes get the following warning message: "V appears to be not
positive definite". 1. Should this be ignored?
#The multivariate model (all clear so far, except for positive definite
warning):
res <- rma.mv(g, V, mods = ~ factor(motivation) - 1, random = ~
factor(motivation) | study, struct="UN", data=meta)
res
#Each level of motivation has its own variance component in the output
(tau). 2. How could I obtain the Q-values (and consequently I squared) to
report?
#If I now wanted to do a moderator analysis with each level of motivation
using the categorical variable "setting"
#to see if there is significant difference between the two settings for
motivation 1,2,3 etc. 3. Would the following be correct?
res <- rma.mv(g, V, mods = ~ factor(motivation)+
factor(motivation):I(setting) -1, random = ~ factor(motivation) | study,
struct="UN", data=meta)
res
res <- rma.mv(g, V, mods = ~ factor(motivation)*I(setting) -1, random = ~
factor(motivation) | study, struct="UN", data=meta)
res
#I am not exactly sure what I should be interpreting. I would like to know
if setting moderates the effect of the intervention on motivation levels
1,2,3,4,5,6 (or can I do that - is the comparison done "overall"? )
#Same goes for the Egger's type test, 4. how should the results of the
moderator analyses be interpreted if I were to use the variance estimate or
its inverse (v) as the predictor to test for publication bias/funnel plot
asymmetry
#5. Any other advice to report the results (e.g., how to display the forest
plot and is there any sense to do a funnel plot?)
###Thank you in advance!###
Mika
[[alternative HTML version deleted]]
More information about the R-sig-meta-analysis
mailing list