[R-meta] Network Meta-analysis metafor
Viechtbauer Wolfgang (SP)
wolfgang.viechtbauer at maastrichtuniversity.nl
Wed Feb 14 13:16:04 CET 2018
Dear Caroline,
The example in help(dat.senn2013) uses mean differences to illustrate a network MA with metafor but is easy to adjust to standardized mean differences. For SMDs, you have to use a contrast-based model. The dat.senn2013 dataset is given in an arm-based format, so it first needs to be restructured. Note that Willms (1999) is the only multiarm study in this dataset, but the code should work regardless of how many multiarm studies there are. Just make sure that the 'reference' treatment for multiarm studies always goes under 'trt1'.
library(metafor)
############################################################################
### load data
dat <- get(data(dat.senn2013, package="metafor"))
### restructure dataset to a contrast-based format
dat <- dat.senn2013[,c(1,4,3,2,5,6)]
dat.c <- lapply(split(dat, dat$study),
function(x) cbind(x[rep(1,nrow(x)-1),], x[-1,c(3:6)]))
dat.c <- do.call(rbind, dat.c)
names(dat.c)[3:10] <- c("trt1", "n1i", "m1i", "sd1i", "trt2", "n2i", "m2i", "sd2i")
rownames(dat.c) <- 1:nrow(dat.c)
dat.c$id <- 1:nrow(dat.c)
dat <- dat.c
rm(dat.c)
############################################################################
### make sure dataset is sorted by 'study'
dat <- dat[order(dat$study),]
### compute the total sample sizes of the studies
dat$Ni <- unlist(lapply(split(dat, dat$study), function(x) rep(x$n1i[1] + sum(x$n2i), each=nrow(x))))
### compute the pooled SDs of the studies
dat$sdpi <- unlist(lapply(split(dat, dat$study), function(x) sqrt(((x$n1i[1]-1)*x$sd1i^2 + sum((x$n2i-1)*x$sd2i^2)) / ((x$n1i[1] - 1) + sum(x$n2i - 1)))))
### calculate SMDs and corresponding sampling variances
dat$yi <- with(dat, (m1i-m2i)/sdpi)
dat$vi <- with(dat, 1/n1i + 1/n2i + yi^2/(2*Ni))
### calculate the variance-covariance matrix of the SMDs for multitreatment studies
calc.v <- function(x) {
v <- matrix(1/x$n1i[1] + outer(x$yi, x$yi, "*")/(2*x$Ni[1]), nrow=nrow(x), ncol=nrow(x))
diag(v) <- x$vi
v
}
V <- bldiag(lapply(split(dat, dat$study), calc.v))
### convert trt1 and trt2 variables to factors and set levels
lvls <- levels(factor(c(dat$trt1, dat$trt2)))
dat$trt1 <- factor(dat$trt1, levels=lvls)
dat$trt2 <- factor(dat$trt2, levels=lvls)
### create variables to indicate the contrasts examined
dat <- cbind(dat, model.matrix(~ dat$trt1 - 1) - model.matrix(~ dat$trt2 - 1))
names(dat)[(ncol(dat)-9):ncol(dat)] <- lvls
############################################################################
### network meta-analysis using a contrast-based random-effects model
### by setting rho=1/2, tau^2 reflects the amount of heterogeneity for all treatment comparisons
### the treatment left out (placebo) becomes the reference level for the treatment comparisons
res <- rma.mv(yi, V, mods = ~ acarbose + benfluorex + metformin + miglitol + pioglitazone +
rosiglitazone + sitagliptin + sulfonylurea + vildagliptin - 1,
random = ~ factor(id) | study, rho=1/2, data=dat)
res
### estimate/test all pairwise differences between treatments
### need 'multcomp' package for contrMat() function
library(multcomp)
contr <- contrMat(setNames(rep(1,res$p), colnames(res$X)), type="Tukey")
sav <- predict(res, newmods=contr)
sav[["slab"]] <- rownames(contr)
sav$pval <- anova(res, L=contr)$pval
sav
############################################################################
Two points:
1) Note that I am using the pooled SD of all arms within each trial to compute the SMDs. That way, results within trials are internally consistent (i.e., A vs B = (A vs C) - (B vs C) for a three-arm study). If you just use the pooled SD of each pairwise comparison, then this won't be the case.
2) I see that you have the reference treatment listed under treat2. If you want to use the code above, just rename your variables to: study trt2 trt1 n2i m2i sd2i n1i m1i sd1i.
Best,
Wolfgang
--
Wolfgang Viechtbauer, Ph.D., Statistician | Department of Psychiatry and
Neuropsychology | Maastricht University | P.O. Box 616 (VIJV1) | 6200 MD
Maastricht, The Netherlands | +31 (43) 388-4170 | http://www.wvbauer.com
>-----Original Message-----
>From: R-sig-meta-analysis [mailto:r-sig-meta-analysis-bounces at r-
>project.org] On Behalf Of Caroline Woehl
>Sent: Wednesday, 14 February, 2018 8:45
>To: r-sig-meta-analysis at r-project.org
>Subject: [R-meta] Network Meta-analysis metafor
>
>Dear all,
>
>I've only calucated network meta-analyses with the package netmeta yet.
>Due to the possibility to calculate subgroup analyses, I'd like to have
>a try at a network meta-analysis with metafor.
>
>The analysis is based on 20 randomized controlled trials. They compare
>physical activity or cognitive activity with usual care. One of them is
>a multi-arm trial comparing physical and cognitive activity with usual
>care. I could extract sample size, mean und standard deviation
>(posttreatment) from each study arm. Thus, the file contains the study,
>treat1, treat2, n1i, m1i, sd1i, n2i, m2i and sd2i.
>
>Study treat1 treat2
> n1i m1i sd1i n2i m2i sd2i
> 1 physical activity usual care 37 17,16 4,33
>36 15,17 4,48
> 2 physical activity usual care 39
>19,40 8,68 35 18,48 8,40
> 2 cognitive activity usual care 36
>19,98 8,16 35 18,48 8,40
> 3 cognitive activity usual care 35 42,34 9,30 33
> 44,49 9,53
>
>So far, I’ve calculated the standardized mean differences (yi) and
>variances (vi) for each pairwise comparison.
>nma <- escalc(measure="SMD", m1i=m1i, sd1i=sd1i, n1i=n1i, m2i=m2i,
>sd2i=sd2i, n2i=n2i, data=nma)
>
>How can I define usual care as the reference group in the next step?
>
>Many thanks for your help.
>
>Best regards,
>Caroline
More information about the R-sig-meta-analysis
mailing list