scores_long <- res |>
select(model, factor, scores) |>
pmap(\(model, factor, scores) {
scores |> select(run_id, value = all_of(factor)) |>
# mirt >= 1.46 fscores columns can arrive as classed 1-col matrices
mutate(value = as.numeric(value), model = model, factor = factor)
}) |> list_rbind()
sum_scores <- coded |>
group_by(run_id) |> summarise(value = mean(correct)) |>
mutate(model = "sumscore", factor = "F1")
scores_long <- bind_rows(scores_long, sum_scores)
scored <- scores_long |> left_join(run_meta, by = "run_id")
age_cors <- scored |>
summarise(r_age = cor(value, age, use = "complete.obs"), .by = c(model, factor))
retest_pairs <- scored |>
filter(dataset == "pilot_mpieva_de_main") |>
group_by(model, factor, user_id) |>
filter(n() == 2) |>
arrange(t_start, .by_group = TRUE) |>
summarise(t1 = value[1], t2 = value[2], age1 = age[1], .groups = "drop")
boot_ci <- function(t1, t2, R = 2000) {
b <- boot(tibble(t1, t2), \(d, i) cor(d$t1[i], d$t2[i], use = "complete.obs"), R = R)
ci <- boot.ci(b, type = "perc")$percent[4:5]
tibble(r_retest = b$t0, ci_lo = ci[1], ci_hi = ci[2])
}
retest_cors <- retest_pairs |>
group_by(model, factor) |>
summarise(boot_ci(t1, t2), n_retest = n(), .groups = "drop")
eval_table <- res |>
select(model, factor, nfact, invariance, itemtype, converged,
emp_rxx, marg_rxx, AIC, BIC, npar, logLik) |>
bind_rows(tibble(model = "sumscore", factor = "F1")) |>
left_join(age_cors, by = c("model", "factor")) |>
left_join(retest_cors, by = c("model", "factor"))
n_retest <- retest_cors$n_retest[1]
fmt_retest <- \(r, lo, hi) glue("{sprintf('%.2f', r)} [{sprintf('%.2f', lo)}, {sprintf('%.2f', hi)}]")
gv <- function(m, col, f = "F1") eval_table[[col]][eval_table$model == m & eval_table$factor == f][1]
model_labels <- tribble(
~model, ~structure, ~floors, ~itemtype_l,
"sumscore", "proportion correct", "—", "—",
"m0_rasch", "block × choice", "corpus (production)", "Rasch",
"m0_2pl", "block × choice", "corpus (production)", "2PL",
"m0c_rasch", "block × choice", "principled (mean)", "Rasch",
"m0z_rasch", "block × choice", "none", "Rasch",
"m1_rasch", "block × choice × status", "principled", "Rasch",
"m1_2pl", "block × choice × status", "principled", "2PL",
"m1z_rasch", "block × choice × status", "none", "Rasch",
"m1z_2pl", "block × choice × status", "none", "2PL",
"m1z_sig_rasch", "block × choice × status × features", "none", "Rasch",
"t1_rasch", "tree nodes, 1 factor", "principled", "Rasch",
"t1z_rasch", "tree nodes, 1 factor", "none", "Rasch",
"t1z_2pl", "tree nodes, 1 factor", "none", "2PL",
"t2zc_rasch", "tree nodes, 2 corr. factors", "none", "Rasch",
"t3z_rasch", "tree nodes, 3 corr. factors", "none", "Rasch")