knitr::opts_chunk$set(
message = FALSE,
warning = FALSE,
include = TRUE,
error = FALSE,
fig.width=7,
fig.height=5
)
library(groundhog)
groundhog.library(c("tidyverse", "kableExtra", "MAd", "meta"), date = "2024-02-14")
windowsFonts(Times = windowsFont("Times New Roman"))
options(scipen = 999, digits = 3)
theme_set(theme_minimal(base_size = 12, base_family = "Times"))
MA1 <- readRDS("data/preprocessed/MA1.rds")
# average group sample size
mean((MA1$nc_ma + MA1$nt_ma) / 2)
## [1] 13
Between-groups studies which reported sample sizes, means and SDs (SEs/CIs)
MA1 <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd") %>%
mutate(d = abs(d)) %>%
# relocate to facilitate inspection
relocate(c(id_comparison, d, smd_ma), .after = dv_ps)
The SMDs that could not be reproduced or approximated (those based on values from figures can only be approximated due to variations in how values were extracted from figures): (4/17 comparisons from between-groups studies). Reproduced SMDs 16, 17, 18, and 20 deviate from the reported ones beyond what would be expected as a result of rounding or differences in how values were extracted from figures. For SMDs 16 and 20, other values could have been used:
For SMD 16, another set of means and SDs could have been used:
compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA1, denom = "pooled.sd")$d[[16]]
## [1] 1.43
Reproduces reported SMD successfully.
SMD 20 had corresponding \(p\)-value:
p_to_d1(MA1$p_ps[[20]], MA1$nt_ps[[20]], MA1$nc_ps[[20]])[1]
## [1] 0.672
p_to_d2(MA1$p_ps[[20]], MA1$nt_ps[[20]], MA1$nc_ps[[20]])[1]
## [1] 0.718
The SMD based on the two tailed \(p\) value successfully reproduces the reported SMD.
Crossover studies which reported sample sizes, means and SDs (SEs/CIs)
Since the meta-analysts listed the sample size of both the treatment and control group as = \(N\) = the number of participants, I use N as the sample size of both groups even though there aren’t two groups:
MA1_co <- MA1 %>% filter(is.na(nc_ps))
MA1_co <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1_co, denom = "pooled.sd")
Reproduced SMDs 12, 13, 21 deviate from the reported ones beyond what would be expected as a result of rounding or differences in how values were extracted from figures. For SMDs 12 and 13, other values could have been used: SMDs 12 and 13 and 21 had another set of means and SDs:
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA1, denom = "pooled.sd")$d[[12]]
## [1] 1.63
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA1, denom = "pooled.sd")$d[[13]]
## [1] 1.61
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA1, denom = "pooled.sd")$d[[21]]
## [1] 1.41
Still not reproducible. SMD 13 does reproduce the Cohen’s \(d\) reported in the primary study, though.
Data extraction was correct for all SMDs and no further data were extracted (see data sheets column “comments” for sources of data).
3 meta-analytic models were fit to each meta-analysis:
# faithfully reproduced SMDs
MA1$smd_re1 <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d
MA1$smd_re1[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d[[2]]
MA1$smd_re1[[21]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d[[21]]
# Brute-force reproduced SMDs
MA1$smd_re1[[19]] <- NA
MA1$smd_re1[[20]] <- NA
MA1$smd_re1[[12]] <- NA
MA1$smd_re1[[13]] <- NA
# make numeric and positive
MA1$smd_re1 <- MA1$smd_re1 %>% as.numeric() %>% abs()
# relocate to check if everything's fine
MA1 <- MA1 %>% relocate(c(id_comparison, smd_re1, smd_ma), .after = dv_ps)
MAd’s compute_ds() and p_to_d1
functions automatically calculate the corresponding sampling/sampling
variances. In cases where not enough data were available, the square of
the standard error extracted from the funnel plot in the MA will be
used.
# SMDs which were successfully reproduced using the first set of means and SDs, in accordance with information in MA
MA1$v_re1 <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d
MA1$v_re1[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d[[2]]
# SMDs which could not be reproduced using the first set of means and SDs, in accordance with information in MA
MA1$v_re1[[21]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d[[21]]
# SMDs which were successfully reproduced using values that either do not quite correspond to the information given in the MA or the standard method adopted for the other SMDs
# MA1$v_re1[[16]] <- NA
MA1$v_re1[[19]] <- NA
MA1$v_re1[[20]] <- NA
# SMDs which could not be reproduced using values that either do not quite correspond to the information given in the MA or the standard method adopted for the other SMDs
MA1$v_re1[[12]] <- NA
MA1$v_re1[[13]] <- NA
# make numeric
MA1$v_re1 <- as.numeric(MA1$v_re1)
# relocate to check if everything's fine
MA1$v_ma <- MA1$se_ma^2
MA1 <- MA1 %>% relocate(c(id_comparison, v_re1, v_ma), .after = dv_ps)
# SMDs which were successfully reproduced using the first set of means and SDs, in accordance with information in MA
MA1$smd_re2 <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d
# SMDs which could not be reproduced using the first set of means and SDs, in accordance with information in MA
MA1$smd_re2[[21]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d[[21]]
# SMDs which were successfully reproduced using values that either do not quite correspond to the information given in the MA or the standard method adopted for the other SMDs
MA1$smd_re2[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d[[2]]
MA1$smd_re2[[16]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA1, denom = "pooled.sd")$d[[16]]
MA1$smd_re2[[19]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d[[19]]
MA1$smd_re2[[20]] <- p_to_d2(MA1$p_ps[[20]], MA1$nt_ps[[20]], MA1$nc_ps[[20]])[1]
# SMDs which could not be reproduced using values that either do not quite correspond to the information given in the MA or the standard method adopted for the other SMDs
MA1$smd_re2[[12]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d[[12]]
MA1$smd_re2[[13]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$d[[13]]
# make numeric and positive
MA1$smd_re2 <- MA1$smd_re2 %>% as.numeric() %>% abs()
# relocate to check if everything's fine
MA1 <- MA1 %>% relocate(smd_re2, .after = smd_re1)
# SMDs which were successfully reproduced using the first set of means and SDs, in accordance with information in MA
MA1$v_re2 <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d
MA1$v_re2[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d[[2]]
# SMDs which could not be reproduced using the first set of means and SDs, in accordance with information in MA
MA1$v_re2[[21]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d[[21]]
# SMDs which were successfully reproduced using values that either do not quite correspond to the information given in the MA or the standard method adopted for the other SMDs
MA1$v_re2[[16]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA1, denom = "pooled.sd")$var.d[[16]]
MA1$v_re2[[19]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d[[19]]
MA1$v_re2[[20]] <- p_to_d2(MA1$p_ps[[20]], MA1$nt_ps[[20]], MA1$nc_ps[[20]])[2]
# SMDs which could not be reproduced using values that either do not quite correspond to the information given in the MA or the standard method adopted for the other SMDs
MA1$v_re2[[12]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d[[12]]
MA1$v_re2[[13]] <- MA1$smd_re2[[13]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA1, denom = "pooled.sd")$var.d[[13]]
# make numeric
MA1$v_re2 <- as.numeric(MA1$v_re2)
# relocate to check if everything's fine
MA1$v_ma <- MA1$se_ma^2
MA1 <- MA1 %>% relocate(c(id_comparison, v_re2, v_ma), .after = dv_ps)
mam1 <- metagen(TE = smd_re1,
seTE = sqrt(v_re1),
studlab = id_comparison,
data = MA1,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(mam1,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "d", "SE"))
mam2 <- metagen(TE = smd_re2,
seTE = sqrt(v_re2),
studlab = id_comparison,
data = MA1,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(mam2,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "d", "SE"))
mam3 <- metagen(TE = smd_ma,
seTE = se_ma,
studlab = id_comparison,
data = MA1,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(mam3,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "d", "SE"))
MA2 <- readRDS("data/preprocessed/MA2.rds")
# average group sample size
mean((MA2$nc_ma + MA2$nt_ma) / 2)
## [1] 12.2
Between-groups studies which reported sample sizes, means and SDs (SEs/CIs)
#MA2 <- compute_dgs(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2, denom = "pooled.sd")
# relocate to facilitate inspection
#MA2 <- MA2 %>% relocate(c(d, g, smd_ma), .after = dv_ps)
For PSs that reported means and SDs (no extraction from figure necessary), all reported SMDs were approximated better by Cohen’s \(d\)s than Hedges’ \(g\)s. I will thus assume the authors used Cohen’s \(d\)s:
MA2 <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2, denom = "pooled.sd")
# relocate to facilitate inspection
MA2 <- MA2 %>% relocate(c(id_comparison, d, smd_ma), .after = dv_ps)
Reproduced SMDs 6, 7, 9, 12, 14, 15 deviate from the reported ones beyond what would be expected as a result of rounding or differences in how values were extracted from figures. For SMDs 6, 7, 14, and 15, other values could have reasonably been used:
SMDs 6 and 7 had corresponding \(p\)-values:
# one-tailed p-value + sample sizes to d
p_to_d1(0.925, 6, 5)[1]
## [1] -0.953
p_to_d1(0.897, 6, 5)[1]
## [1] -0.825
# two-tailed p-value + sample sizes to d
p_to_d2(0.925, 6, 5)[1]
## [1] 0.0586
p_to_d2(0.897, 6, 5)[1]
## [1] 0.0806
Since these are even further from the ones based on means and SDs, data extraction was double checked for correctness (see below).
For SMDs 14 and 15, two other sets of means and SDs could have been used:
# Set 2
compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[14]]
## [1] 1.84
compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[15]]
## [1] 1.16
# Set 3
compute_ds(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.3, sdc_ps.3, data = MA2, denom = "pooled.sd")$d[[14]]
## [1] 1.43
compute_ds(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.3, sdc_ps.3, data = MA2, denom = "pooled.sd")$d[[15]]
## [1] 1.01
Values of set 2 are much closer, but not quite identical.
Crossover studies which reported sample sizes, means and SDs (SEs/CIs) Since the meta-analysts listed the sample size of both the treatment and control group as = \(N\) = the number of participants, I use N as the sample size of both groups even though there aren’t two groups:
MA22 <- MA2 %>% filter(is.na(nc_ps))
MA22 <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA22, denom = "pooled.sd")
Reproduced SMDs 1, 2, 4, 5, 13, 20 deviate from the reported ones beyond what would be expected as a result of rounding or differences in how values were extracted from figures. For SMDs 1, 2, 4, 5, and 20, other values could have reasonably been used:
SMD 1 had two other sets of means and SDs and a corresponding \(p\) value:
# Set 2
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[1]]
## [1] 0
# Set 3
compute_ds(n_ps, mt_ps.3, sdt_ps.3, n_ps, mc_ps.3, sdc_ps.3, data = MA2, denom = "pooled.sd")$d[[1]]
## [1] -0.38
# p-value
p_to_d1(MA2$p_ps[[1]], MA2$n_ps[[1]], MA2$n_ps[[1]])[1]
## [1] 1.07
p_to_d2(MA2$p_ps[[1]], MA2$n_ps[[1]], MA2$n_ps[[1]])[1]
## [1] 1.22
The \(d\) based on the one-tailed \(p\)-values is closest.
SMD 2 had a corresponding \(p\) value:
p_to_d1(MA2$p_ps[[2]], MA2$n_ps[[2]], MA2$n_ps[[2]])[1]
## [1] 1.97
p_to_d2(MA2$p_ps[[2]], MA2$n_ps[[2]], MA2$n_ps[[2]])[1]
## [1] 2.35
Closer.
SMDs 4, 5, and 20 had another set of means and SDs:
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[4]]
## [1] -0.542
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[5]]
## [1] 0.378
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[20]]
## [1] 1.41
Nope.
Studies which did not report means and/or SDs (SEs/CIs) For SMD 8, only means were reported. Computing an SMD is thus not possible. For SMD 19 no means or SDs were reported but a potentially suitable \(p\)-value:
p_to_d1(MA2$p_ps[[19]], MA2$n_ps[[19]], MA2$n_ps[[19]])[1]
## [1] 0.946
p_to_d2(MA2$p_ps[[19]], MA2$n_ps[[19]], MA2$n_ps[[19]])[1]
## [1] 1.11
The one-tailed one is close enough.
For SMD 3, an SMD was reported in the primary study which was close to the one reported in the MA.
Reproduce SMDs 6 & 7 using values extracted from figures:
# Convert upper bounds of SD bars extracted from figures to SDs
MA2[6, "sdc_ps.2"] <- (MA2[6, "sdc_ps.2"] - MA2[6, "mc_ps.2"])
MA2[6, "sdt_ps.2"] <- (MA2[6, "sdt_ps.2"] - MA2[6, "mt_ps.2"])
MA2[7, "sdc_ps.2"] <- (MA2[7, "sdc_ps.2"] - MA2[7, "mc_ps.2"])
MA2[7, "sdt_ps.2"] <- (MA2[7, "sdt_ps.2"] - MA2[7, "mt_ps.2"])
# Compute Cohen's ds
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[6]]
## [1] 0.412
compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2, denom = "pooled.sd")$d[[7]]
## [1] 0.355
Reproduce SMDs 8 & 9 using \(p\)-values:
p_to_d2(MA2$p_ps[[8]], MA2$nc_ps[[8]], MA2$nt_ps[[8]])[1]
## [1] 0.136
p_to_d2(MA2$p_ps[[9]], MA2$nc_ps[[9]], MA2$nt_ps[[9]])[1]
## [1] 0.109
MA2$smd_re1[[1]] <- NA
MA2$smd_re1[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[2,], denom = "pooled.sd")$d
MA2$smd_re1[[3]] <- NA
MA2$smd_re1[[4]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[4,], denom = "pooled.sd")$d
MA2$smd_re1[[5]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[5,], denom = "pooled.sd")$d
MA2$smd_re1[[6]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[6,], denom = "pooled.sd")$d
MA2$smd_re1[[7]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[7,], denom = "pooled.sd")$d
MA2$smd_re1[[8]] <- NA
MA2$smd_re1[[9]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[9,], denom = "pooled.sd")$d
MA2$smd_re1[[10]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[10,], denom = "pooled.sd")$d
MA2$smd_re1[[11]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[11,], denom = "pooled.sd")$d %>% abs()
MA2$smd_re1[[12]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[12,], denom = "pooled.sd")$d
MA2$smd_re1[[13]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[13,], denom = "pooled.sd")$d
MA2$smd_re1[[14]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[14,], denom = "pooled.sd")$d
MA2$smd_re1[[15]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[15,], denom = "pooled.sd")$d
MA2$smd_re1[[16]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[16,], denom = "pooled.sd")$d
MA2$smd_re1[[17]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[17,], denom = "pooled.sd")$d
MA2$smd_re1[[18]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[18,], denom = "pooled.sd")$d %>% abs()
MA2$smd_re1[[19]] <- -p_to_d1(MA2$p_ps[[19]], MA2$n_ps[[19]], MA2$n_ps[[19]])[1]
MA2$smd_re1[[20]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[20,], denom = "pooled.sd")$d
# make numeric
MA2$smd_re1 <- MA2$smd_re1 %>% as.numeric()
# relocate to check if everything's fine
MA2 <- MA2 %>% relocate(c(id_comparison, smd_re1, smd_ma), .after = dv_ps)
MA2$v_re1[[1]] <- NA
MA2$v_re1[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[2,], denom = "pooled.sd")$var.d
MA2$v_re1[[3]] <- NA
MA2$v_re1[[4]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[4,], denom = "pooled.sd")$var.d
MA2$v_re1[[5]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[5,], denom = "pooled.sd")$var.d
MA2$v_re1[[6]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[6,], denom = "pooled.sd")$var.d
MA2$v_re1[[7]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[7,], denom = "pooled.sd")$var.d
MA2$v_re1[[8]] <- NA
MA2$v_re1[[9]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[9,], denom = "pooled.sd")$var.d
MA2$v_re1[[10]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[10,], denom = "pooled.sd")$var.d
MA2$v_re1[[11]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[11,], denom = "pooled.sd")$var.d
MA2$v_re1[[12]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[12,], denom = "pooled.sd")$var.d
MA2$v_re1[[13]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[13,], denom = "pooled.sd")$var.d
MA2$v_re1[[14]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[14,], denom = "pooled.sd")$var.d
MA2$v_re1[[15]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[15,], denom = "pooled.sd")$var.d
MA2$v_re1[[16]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[16,], denom = "pooled.sd")$var.d
MA2$v_re1[[17]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[17,], denom = "pooled.sd")$var.d
MA2$v_re1[[18]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[18,], denom = "pooled.sd")$var.d
MA2$v_re1[[19]] <- p_to_d1(MA2$p_ps[[19]], MA2$n_ps[[19]], MA2$n_ps[[19]])[2]
MA2$v_re1[[20]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[20,], denom = "pooled.sd")$var.d
# make numeric
MA2$v_re1 <- MA2$v_re1 %>% as.numeric()
# relocate to check if everything's fine
MA2$v_ma <- MA2$se_ma^2
MA2 <- MA2 %>% relocate(c(id_comparison, v_re1, v_ma), .after = dv_ps)
MA2$smd_re2[[1]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[1,], denom = "pooled.sd")$d
MA2$smd_re2[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[2,], denom = "pooled.sd")$d
MA2$smd_re2[[3]] <- MA2$smd_ps[[3]]
MA2$smd_re2[[4]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[4,], denom = "pooled.sd")$d
MA2$smd_re2[[5]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[5,], denom = "pooled.sd")$d
MA2$smd_re2[[6]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[6,], denom = "pooled.sd")$d
MA2$smd_re2[[7]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[7,], denom = "pooled.sd")$d
MA2$smd_re2[[8]] <- -p_to_d2(MA2$p_ps[[8]], MA2$nc_ps[[8]], MA2$nt_ps[[8]])[1]
MA2$smd_re2[[9]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[9,], denom = "pooled.sd")$d
MA2$smd_re2[[10]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[10,], denom = "pooled.sd")$d
MA2$smd_re2[[11]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[11,], denom = "pooled.sd")$d %>% abs()
MA2$smd_re2[[12]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[12,], denom = "pooled.sd")$d
MA2$smd_re2[[13]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[13,], denom = "pooled.sd")$d
MA2$smd_re2[[14]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[14,], denom = "pooled.sd")$d
MA2$smd_re2[[15]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[15,], denom = "pooled.sd")$d
MA2$smd_re2[[16]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[16,], denom = "pooled.sd")$d
MA2$smd_re2[[17]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[17,], denom = "pooled.sd")$d
MA2$smd_re2[[18]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[18,], denom = "pooled.sd")$d %>% abs()
MA2$smd_re2[[19]] <- -p_to_d1(MA2$p_ps[[19]], MA2$n_ps[[19]], MA2$n_ps[[19]])[1]
MA2$smd_re2[[20]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[20,], denom = "pooled.sd")$d
# make numeric
MA2$smd_re2 <- MA2$smd_re2 %>% as.numeric()
# relocate to check if everything's fine
MA2 <- MA2 %>% relocate(smd_re2, .after = smd_re1)
MA2$v_re2[[1]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[1,], denom = "pooled.sd")$var.d
MA2$v_re2[[2]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[2,], denom = "pooled.sd")$var.d
MA2$v_re2[[3]] <- ((MA2$n_ps[[3]] + MA2$n_ps[[3]]) / (MA2$n_ps[[3]]*MA2$n_ps[[3]])) + (MA2$smd_ps[[3]]^2 / (2 * (MA2$n_ps[[3]] + MA2$n_ps[[3]])))
MA2$v_re2[[4]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[4,], denom = "pooled.sd")$var.d
MA2$v_re2[[5]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[5,], denom = "pooled.sd")$var.d
MA2$v_re2[[6]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[6,], denom = "pooled.sd")$var.d
MA2$v_re2[[7]] <- compute_ds(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA2[7,], denom = "pooled.sd")$var.d
MA2$v_re2[[8]] <- p_to_d2(MA2$p_ps[[8]], MA2$nc_ps[[8]], MA2$nt_ps[[8]])[2]
MA2$v_re2[[9]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[9,], denom = "pooled.sd")$var.d
MA2$v_re2[[10]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[10,], denom = "pooled.sd")$var.d
MA2$v_re2[[11]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[11,], denom = "pooled.sd")$var.d
MA2$v_re2[[12]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[12,], denom = "pooled.sd")$var.d
MA2$v_re2[[13]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[13,], denom = "pooled.sd")$var.d
MA2$v_re2[[14]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[14,], denom = "pooled.sd")$var.d
MA2$v_re2[[15]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[15,], denom = "pooled.sd")$var.d
MA2$v_re2[[16]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[16,], denom = "pooled.sd")$var.d
MA2$v_re2[[17]] <- compute_ds(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA2[17,], denom = "pooled.sd")$var.d
MA2$v_re2[[18]] <- compute_ds(n_ps, mt_ps.1, sdt_ps.1, n_ps, mc_ps.1, sdc_ps.1, data = MA2[18,], denom = "pooled.sd")$var.d
MA2$v_re2[[19]] <- p_to_d1(MA2$p_ps[[19]], MA2$n_ps[[19]], MA2$n_ps[[19]])[2]
MA2$v_re2[[20]] <- compute_ds(n_ps, mt_ps.2, sdt_ps.2, n_ps, mc_ps.2, sdc_ps.2, data = MA2[20,], denom = "pooled.sd")$var.d
# make numeric
MA2$v_re2 <- MA2$v_re2 %>% as.numeric()
mam1 <- metagen(TE = smd_re1,
seTE = sqrt(v_re1),
studlab = id_comparison,
data = MA2,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(mam1,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "d", "SE"))
mam2 <- metagen(TE = smd_re2,
seTE = sqrt(v_re2),
studlab = id_comparison,
data = MA2,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(mam2,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "d", "SE"))
mam3 <- metagen(TE = smd_ma,
seTE = se_ma,
studlab = id_comparison,
data = MA2,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(mam3,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "d", "SE"))
MA3 <- readRDS("data/preprocessed/MA3.rds")
# average group sample size
mean((MA3$nc_ma + MA3$nt_ma) / 2, na.rm = TRUE)
## [1] 16.3
This MA only included RCTs. 1 out of the 6 studies included was a conference abstract which only reported the total sample size. The 5 others reported group sample sizes, 3 reported raw means and SDs, one reported a potentially usable \(t\)-value. Hedges’ \(g\) was used. Studies which reported means and SDs
MA3 <- compute_dgs(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA3, denom = "pooled.sd")
# relocate to facilitate inspection
MA3 <- MA3 %>% relocate(c(id_comparison, g, smd_ma), .after = dv_ps)
SMD 4 was reproduced. SMD 2 was approximated but in the other direction. SMD 5 quite close. Data extraction will be double-checked.
Studies which did not report means and/or SDs
t_to_d(MA3$t_ps[[6]], MA3$nt_ps[[6]], MA3$nc_ps[[6]])[1]
## [1] 0.597
Nope.
MA3$d <- p_to_d2(0.01, MA3$nt_ps[[1]], MA3$nc_ps[[1]])[1]
MA3$vd <- p_to_d2(0.01, MA3$nt_ps[[1]], MA3$nc_ps[[1]])[2]
compute_gs(d, vd, nt_ps, nc_ps, MA3)$g[1]
## [1] 0.84
compute_dgs(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$g
## [1] -0.243
compute_dgs(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA3[2,], denom = "pooled.sd")$g
## [1] -0.308
MA3$mt_ps.3 <- (MA3$mt_ps.1 + MA3$mt_ps.2) / 2
MA3$sdt_ps.3 <- (MA3$sdt_ps.1 + MA3$sdt_ps.2) / 2
compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$g
## [1] -0.275
MA3$mt_ps.3[[2]] <- (MA3$mt_ps.1[[2]] + MA3$mt_ps.2[[2]]) / 2
MA3$sdt_ps.3[[2]] <- (MA3$sdt_ps.1[[2]] + MA3$sdt_ps.2[[2]]) / 2
compute_dgs(nt_ps*2, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$g
## [1] -0.289
compute_dgs(nt_ps*2, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$g
## [1] -0.253
compute_dgs(nt_ps*2, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA3[2,], denom = "pooled.sd")$g
## [1] -0.329
MA3$d <- p_to_d2(0.01, MA3$n_ps[[3]], MA3$n_ps[[3]])[1]
MA3$vd <- p_to_d2(0.01, MA3$n_ps[[3]], MA3$n_ps[[3]])[2]
compute_gs(d, vd, n_ps, n_ps, MA3)$g[3]
## [1] 0.982
5.based on second set
compute_dgs(nt_ps, mt_ps.2, sdt_ps.2, nc_ps, mc_ps.2, sdc_ps.2, data = MA3[5,], denom = "pooled.sd")$g
## [1] 0.396
nope
take average
MA3$mc_ps.3 <- (MA3$mc_ps.1 + MA3$mc_ps.2) / 2
MA3$mt_ps.3 <- (MA3$mt_ps.1 + MA3$mt_ps.2) / 2
MA3$sdc_ps.3 <- (MA3$sdc_ps.1 + MA3$sdc_ps.2) / 2
MA3$sdt_ps.3 <- (MA3$sdt_ps.1 + MA3$sdt_ps.2) / 2
compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.3, sdc_ps.3, data = MA3[5,], denom = "pooled.sd")$g
## [1] 0.565
yup
MA3$d <- p_to_d2(0.169, MA3$nc_ps[[6]], MA3$nt_ps[[6]])[1]
MA3$vd <- p_to_d2(0.169, MA3$nc_ps[[6]], MA3$nt_ps[[6]])[2]
compute_gs(d, vd, nt_ps, nc_ps, MA3)$g[6]
## [1] 0.585
yup
# 1
MA3$smd_re1[[1]] <- NA
# 2
MA3$mt_ps.3 <- (MA3$mt_ps.1 + MA3$mt_ps.2) / 2
MA3$sdt_ps.3 <- (MA3$sdt_ps.1 + MA3$sdt_ps.2) / 2
MA3$smd_re1[[2]] <- compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$g %>% abs()
# 3
MA3$smd_re1[[3]] <- NA
# 4
MA3$smd_re1[[4]] <- NA
#5
MA3$mc_ps.3 <- (MA3$mc_ps.1 + MA3$mc_ps.2) / 2
MA3$mt_ps.3 <- (MA3$mt_ps.1 + MA3$mt_ps.2) / 2
MA3$sdc_ps.3 <- (MA3$sdc_ps.1 + MA3$sdc_ps.2) / 2
MA3$sdt_ps.3 <- (MA3$sdt_ps.1 + MA3$sdt_ps.2) / 2
MA3$smd_re1[[5]] <- compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.3, sdc_ps.3, data = MA3[5,], denom = "pooled.sd")$g
#6
MA3$smd_re1[[6]] <- NA
# make numeric
MA3 <- MA3 %>% mutate_at(vars(starts_with('smd')), as.numeric)
# relocate to facilitate inspection
MA3 <- MA3 %>% relocate(c(smd_re1, smd_ma, id_comparison), .after = dv_ps)
# 1
MA3$v_re1[[1]] <- NA
# 2
MA3$v_re1[[2]] <- compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$var.g
# 3
MA3$v_re1[[3]] <- NA
# 4
MA3$v_re1[[4]] <- NA
#5
MA3$mc_ps.3 <- (MA3$mc_ps.1 + MA3$mc_ps.2) / 2
MA3$mt_ps.3 <- (MA3$mt_ps.1 + MA3$mt_ps.2) / 2
MA3$sdc_ps.3 <- (MA3$sdc_ps.1 + MA3$sdc_ps.2) / 2
MA3$sdt_ps.3 <- (MA3$sdt_ps.1 + MA3$sdt_ps.2) / 2
MA3$v_re1[[5]] <- compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.3, sdc_ps.3, data = MA3[5,], denom = "pooled.sd")$var.g
#6
MA3$v_re1[[6]] <- NA
# 1
MA3$d <- p_to_d2(MA3$p_ps[[1]], MA3$nt_ps[[1]], MA3$nc_ps[[1]])[1]
MA3$vd <- p_to_d2(MA3$p_ps[[1]], MA3$nt_ps[[1]], MA3$nc_ps[[1]])[2]
MA3$smd_re2[[1]] <- compute_gs(d, vd, nt_ps, nc_ps, MA3)$g[1]
# 2
MA3$smd_re2[[2]] <- compute_dgs(nt_ps*2, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$g %>% abs()
# 3
MA3$d <- p_to_d2(MA3$p_ps[[3]], MA3$n_ps[[3]], MA3$n_ps[[3]])[1]
MA3$vd <- p_to_d2(MA3$p_ps[[3]], MA3$n_ps[[3]], MA3$n_ps[[3]])[2]
MA3$smd_re2[[3]] <- compute_gs(d, vd, n_ps, n_ps, MA3)$g[3]
# 4
MA3$smd_re2[[4]] <- compute_dgs(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[4,], denom = "pooled.sd")$g
#5
MA3$mc_ps.3 <- (MA3$mc_ps.1 + MA3$mc_ps.2) / 2
MA3$mt_ps.3 <- (MA3$mt_ps.1 + MA3$mt_ps.2) / 2
MA3$sdc_ps.3 <- (MA3$sdc_ps.1 + MA3$sdc_ps.2) / 2
MA3$sdt_ps.3 <- (MA3$sdt_ps.1 + MA3$sdt_ps.2) / 2
MA3$smd_re2[[5]] <- compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.3, sdc_ps.3, data = MA3[5,], denom = "pooled.sd")$g
#6
MA3$d <- p_to_d2(MA3$p_ps[[6]], MA3$nc_ps[[6]], MA3$nt_ps[[6]])[1]
MA3$vd <- p_to_d2(MA3$p_ps[[6]], MA3$nc_ps[[6]], MA3$nt_ps[[6]])[2]
MA3$smd_re2[[6]] <- compute_gs(d, vd, nt_ps, nc_ps, MA3)$g[6]
# make numeric
MA3 <- MA3 %>% mutate_at(vars(starts_with('smd')), as.numeric)
# relocate to facilitate inspection
MA3 <- MA3 %>% relocate(smd_re2, .after = smd_re1)
# 1
MA3$d <- p_to_d2(0.01, MA3$nt_ps[[1]], MA3$nc_ps[[1]])[1]
MA3$vd <- p_to_d2(0.01, MA3$nt_ps[[1]], MA3$nc_ps[[1]])[2]
MA3$v_re2[[1]] <- compute_gs(d, vd, nt_ps, nc_ps, MA3)$var.g[1]
# 2
MA3$v_re2[[2]] <- compute_dgs(nt_ps*2, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[2,], denom = "pooled.sd")$var.g
# 3
MA3$d <- p_to_d2(0.01, MA3$n_ps[[3]], MA3$n_ps[[3]])[1]
MA3$vd <- p_to_d2(0.01, MA3$n_ps[[3]], MA3$n_ps[[3]])[2]
MA3$v_re2[[3]] <- compute_gs(d, vd, n_ps, n_ps, MA3)$var.g[3]
# 4
MA3$v_re2[[4]] <- compute_dgs(nt_ps, mt_ps.1, sdt_ps.1, nc_ps, mc_ps.1, sdc_ps.1, data = MA3[4,], denom = "pooled.sd")$var.g
#5
MA3$mc_ps.3 <- (MA3$mc_ps.1 + MA3$mc_ps.2) / 2
MA3$mt_ps.3 <- (MA3$mt_ps.1 + MA3$mt_ps.2) / 2
MA3$sdc_ps.3 <- (MA3$sdc_ps.1 + MA3$sdc_ps.2) / 2
MA3$sdt_ps.3 <- (MA3$sdt_ps.1 + MA3$sdt_ps.2) / 2
MA3$v_re2[[5]] <- compute_dgs(nt_ps, mt_ps.3, sdt_ps.3, nc_ps, mc_ps.3, sdc_ps.3, data = MA3[5,], denom = "pooled.sd")$var.g
#6
MA3$d <- p_to_d2(0.169, MA3$nc_ps[[6]], MA3$nt_ps[[6]])[1]
MA3$vd <- p_to_d2(0.169, MA3$nc_ps[[6]], MA3$nt_ps[[6]])[2]
MA3$v_re2[[6]] <- compute_gs(d, vd, nt_ps, nc_ps, MA3)$var.g[6]
# make numeric
MA3 <- MA3 %>% mutate_at(vars(starts_with('v_')), as.numeric)
MA3$v_ma <- ((MA3$ciu_ma - MA3$smd_ma) / 1.96)^2
MA3$se_ma <- ((MA3$ciu_ma - MA3$smd_ma) / 1.96)
# compare with reproduced variances
MA3 <- MA3 %>% relocate(c(v_re1, v_re2, v_ma), .after = smd_ma)
ma1 <- metagen(TE = smd_re1,
seTE = sqrt(v_re1),
studlab = id_comparison,
data = MA3,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(ma1,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "g", "SE"))
ma2 <- metagen(TE = smd_re2,
seTE = sqrt(v_re2),
studlab = id_comparison,
data = MA3,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(ma2,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "g", "SE"))
ma3 <- metagen(TE = smd_ma,
seTE = se_ma,
studlab = as.character(id_comparison),
data = MA3,
sm = "SMD",
fixed = FALSE,
random = TRUE, # a random effects MA.
method.tau = "DL", # DerSimonian-Laird estimator
)
forest(ma3,
fontfamily = "Times",
print.tau2 = TRUE,
leftlabs = c("SMD No.", "g", "SE"))
MA_all <- MA1 %>%
bind_rows(MA2) %>%
bind_rows(MA3) %>%
mutate(dif = smd_ma - smd_re1,
abs_dif = abs(smd_ma - smd_re1))
saveRDS(MA_all, "data/preprocessed/MA_all.rds")
mean(MA_all$dif, na.rm = T)
## [1] 0.161
max(MA_all$dif, na.rm = T)
## [1] 2.99
min(MA_all$dif, na.rm = T)
## [1] -1.08
mean(MA_all$abs_dif, na.rm = T)
## [1] 0.372
max(MA_all$abs_dif, na.rm = T)
## [1] 2.99
min(MA_all$abs_dif, na.rm = T)
## [1] 0.000464
MA_all <- MA_all %>%
mutate(id_ma = as.character(id_ma))
ggplot(MA_all, aes(smd_ma, round(smd_re1, 2))) +
geom_abline(slope = 1, linetype = "dotted") +
geom_point(aes(color = id_ma, shape = id_ma), size = 2.25) +
theme_classic(base_family = "Times", base_size = 12)+
labs(
x = "Reported primary ES",
y = "Reproduced primary ES",
color = "Meta-analysis ID",
shape = "Meta-analysis ID"
) +
annotate("text", x = 0, y = 1.80, size = 4, label = "Undererstimates ES", family = "Times") +
annotate("text", x = 1, y = -.5, size = 4, label = "Overestimates ES", family = "Times") +
scale_colour_manual(values = c("#009e73", "#0072b2", "#e69f00")) + theme(aspect.ratio=1)
ggplot(MA_all, aes(smd_ma, round(smd_re2, 2))) +
geom_abline(slope = 1, linetype = "dotted") +
geom_point(aes(color = id_ma, shape = id_ma), size = 2.25) +
theme_classic(base_family = "Times", base_size = 12)+
labs(
x = "Reported primary SMD",
y = "Faithfully & brute-force reproduced primary SMD",
color = "Meta-analysis ID",
shape = "Meta-analysis ID"
) +
annotate("text", x = 0, y = 1.80, size = 4, label = "Underestimates ES", family = "Times") +
annotate("text", x = 1, y = -.5, size = 4, label = "Overestimates ES", family = "Times") +
scale_colour_manual(values = c("#009e73", "#0072b2", "#e69f00")) + theme(aspect.ratio=1)