R notebook for:
options(
digits = 3
)
library(pacman)
p_load(kirkegaard, rms, metafor, googlesheets4, metaviz)
theme_set(theme_bw())
gs4_auth("the.dfx@gmail.com")
d = read_sheet("https://docs.google.com/spreadsheets/d/1tFr_ZAGz1gpEeCsFCJ6oRfiqwMP1z3ScGbVLYRFpWyQ/edit?ts=5f3339c5#gid=0") %>%
df_legalize_names()
## Reading from "A meta-analysis of ethnic Russian intelligence: tables"
## Range "Лист1"
#age function
estimate_age = function(x) {
# browser()
#find up to two numbers
num_matches = str_match_all(x, "[\\d\\.]+")[[1]]
#take mean
return(num_matches %>% as.numeric() %>% mean(na.rm=T))
#more? error
stop("Unexpected data format", call. = F)
}
#derived data
d %<>% mutate(
#fix score
mean = Score %>% as.numeric(),
mean_se = 15/sqrt(N),
#fix reference
Reference = str_replace(Reference, ",\\n", " "),
#year
year = str_match(Reference, "\\d+") %>% as.numeric(),
#estimate mean age from age range
mean_age = map_dbl(Age, estimate_age),
#military or not
military = Test == "Military test"
)
#manually code age for military men as 20
d$mean_age[d$Sample == "Young men, who want to serve in military"] = 20
#birth year
d$birth_year = d$year - d$mean_age
#sort by birth year
d %<>% arrange(birth_year)
#main fit
main_meta = metafor::rma(yi = mean, sei = mean_se, data = d)
main_meta
##
## Random-Effects Model (k = 83; tau^2 estimator: REML)
##
## tau^2 (estimated amount of total heterogeneity): 9.7808 (SE = 1.5902)
## tau (square root of estimated tau^2 value): 3.1274
## I^2 (total heterogeneity / total variability): 99.13%
## H^2 (total variability / sampling variability): 114.60
##
## Test for Heterogeneity:
## Q(df = 82) = 3233.1271, p-val < .0001
##
## Model Results:
##
## estimate se zval pval ci.lb ci.ub
## 99.4602 0.3510 283.3536 <.0001 98.7722 100.1482 ***
##
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
plot(main_meta)
#forest plot
forest(main_meta)
#better forest plots
metaviz::viz_forest(main_meta,
xlab = "Mean IQ",
study_labels = d$Reference
)
GG_save("figs/forest.png")
metaviz::viz_forest(main_meta,
group = d$military %>% mapvalues(c(T, F), c("Military", "Non-military")),
col = d$military %>% mapvalues(c(T, F), c("red", "blue")),
summary_col = c("red", "blue"),
xlab = "Mean IQ",
study_labels = d$Reference,
variant = "thick"
)
GG_save("figs/forest_military.png")
#meta-regression
mod_meta = metafor::rma(yi = mean, sei = mean_se, mods = ~ mean_age + birth_year + military, data = d)
mod_meta
##
## Mixed-Effects Model (k = 83; tau^2 estimator: REML)
##
## tau^2 (estimated amount of residual heterogeneity): 6.4249 (SE = 1.0763)
## tau (square root of estimated tau^2 value): 2.5347
## I^2 (residual heterogeneity / unaccounted variability): 98.72%
## H^2 (unaccounted variability / sampling variability): 77.94
## R^2 (amount of heterogeneity accounted for): 34.31%
##
## Test for Residual Heterogeneity:
## QE(df = 79) = 2963.3538, p-val < .0001
##
## Test of Moderators (coefficients 2:4):
## QM(df = 3) = 39.2132, p-val < .0001
##
## Model Results:
##
## estimate se zval pval ci.lb ci.ub
## intrcpt -117.0493 44.3300 -2.6404 0.0083 -203.9345 -30.1641 **
## mean_age 0.1390 0.0823 1.6894 0.0911 -0.0223 0.3003 .
## birth_year 0.1069 0.0223 4.8027 <.0001 0.0633 0.1506 ***
## militaryTRUE 0.6482 0.9739 0.6656 0.5057 -1.2606 2.5570
##
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#plot fit
plot(mod_meta)
#plot birth year
ggplot(d, aes(birth_year, mean)) +
geom_point() +
geom_errorbar(aes(ymin = mean - 1.96*mean_se, ymax = mean + 1.96*mean_se)) +
geom_smooth(method = lm) +
scale_x_continuous("Birth year") +
scale_y_continuous("Mean IQ")
## `geom_smooth()` using formula 'y ~ x'
GG_save("figs/birth_year_timeline.png")
## `geom_smooth()` using formula 'y ~ x'