Hi all,
Quick question about metafor::vcalc(): is there a way to specify different within-study correlations for sampling errors depending on study design (e.g., rho = 0.5 for between-subject studies and rho = 0.7 for within-subject studies), rather than using my likely inefficient workaround using clubSandwich::pattern_covariance_matrix() to build V?
I?m currently doing this (toy example below) and would appreciate any guidance on whether vcalc() can handle this directly.
Thanks in advance!
Zhouhan
library(metafor); library(tidyverse); library(clubSandwich)
dat.smc <- read.table(header=T, text="
study time_interval group ni mpre mpost sdpre sdpost design age
A pre-post1 treat 28 0.89 5.07 1.40 3.20 between adult
A pre-post2 treat 28 0.89 3.64 1.40 3.15 between adult
A pre-post1 contl 58 1.22 3.52 1.76 2.58 between young
A pre-post2 contl 58 1.22 2.86 1.76 2.80 between young
B pre-post1 treat 38 1.89 4.07 0.40 2.20 within young
B pre-post1 contl 48 2.22 2.52 0.76 1.58 within young")
datT <- escalc("SMCRP", ni=ni, m1i=mpost, m2i=mpre, sd1i=sdpre, sd2i=sdpost, ri=rep(.7,3), data=subset(dat.smc,group=="treat"))
datC <- escalc("SMCRP", ni=ni, m1i=mpost, m2i=mpre, sd1i=sdpre, sd2i=sdpost, ri=rep(.7,3), data=subset(dat.smc,group=="contl"))
arm <- "group"
id <- c("study","time_interval")
dat <- datT %>%
select(all_of(c(id, "yi", "vi")), everything()) %>%
left_join(datC %>% select(all_of(id), yiC = yi, viC = vi), by = id) %>%
mutate(yi = yi - yiC, vi = vi + viC, effect = row_number()) %>%
select(-yiC, -viC)
# Define larger correlations among effect sizes from within-subjects (0.7)
# than those from between-subjects designs (0.5)
dat2 <- dat %>%
group_by(study) %>%
mutate(rho_study = if_else(first(design) == "within", 0.7, 0.5)) %>%
ungroup()
r_pat <- matrix(c(
0.7, 0.5,
0.5, 0.5
), nrow = 2, byrow = TRUE,
dimnames = list(c("within","between"), c("within","between")))
V <- with(dat2, pattern_covariance_matrix(
vi = vi, cluster = study, pattern_level = design, r_pattern = r_pat, check_PD = TRUE))
m <- rma.mv<http://rma.mv>(yi ~ 0 + time_interval, V, random = ~1|study/effect, data=dat2)