| Title: | Exact and Permutation-Based Mantel Tests for Differential Item Functioning in Dichotomous and Polytomous Items |
|---|---|
| Description: | Screens dichotomous and polytomous test items for Differential Item Functioning (DIF) using an extension of the Mantel (1963) <doi:10.1080/01621459.1963.10500879> and generalized Mantel-Haenszel statistic, with statistical significance computed via permutation rather than the conventional asymptotic chi-square approximation. Following Hemerik and Goeman (2018) <doi:10.1007/s11749-017-0571-1>, the permutation p-value is exact at the nominal level rather than an approximation, even for a finite number of permutations. This makes the test valid for small samples (fewer than 200 examinees per group), a condition common in classroom-, program-, and institution-level assessment where existing exact-inference options in other software are restricted to dichotomous items only. An optional Benjamini-Hochberg or Bonferroni correction addresses multiple comparisons when screening many items at once. |
| Authors: | Tri Zahra Ningsih [aut, cre], Aman [aut], Ahmad Nasrulloh [aut], Hera Hastuti [aut], Suci Kurnia Putri [aut] |
| Maintainer: | Tri Zahra Ningsih <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.1.0 |
| Built: | 2026-10-09 10:13:14 UTC |
| Source: | https://github.com/cran/exactGMH |
Computes the Mantel (1963) / Mantel-Haenszel DIF statistic for a single dichotomous or polytomous item, with statistical significance obtained via permutation of group membership within score-matched strata. Following Hemerik and Goeman (2018), the observed statistic is included among the reference draws (the "+1" correction), which guarantees the resulting p-value is exact at the nominal level rather than merely an asymptotic approximation, even for a finite number of permutations.
exact_mantel_dif(item_score, group, total_score, n_perm = 5000, seed = 123)exact_mantel_dif(item_score, group, total_score, n_perm = 5000, seed = 123)
item_score |
Numeric vector of item scores: 0/1 for dichotomous items, or 0..C-1 for polytomous items (e.g., a 5-point rubric coded 0-4). |
group |
Vector of group membership (exactly 2 levels, e.g.,
|
total_score |
Numeric vector used as the matching/stratification variable, typically the total test score computed after removing the item under study. |
n_perm |
Integer; number of permutations (default 5000). Larger values give a more precise p-value at the cost of computation time. |
seed |
Integer; random seed for reproducibility (default 123). |
A one-row data frame with columns:
"Dichotomous" or "Polytomous" (auto-detected).
Standardized Mantel statistic.
Delta-MH (dichotomous) or standardized difference (polytomous).
Label describing the effect size column.
Asymptotic chi-square statistic (for comparison).
p-value from the conventional asymptotic chi-square approximation.
Exact permutation-based p-value (recommended).
ETS-style DIF classification: "A (negligible)", "B (moderate)", or "C (large)".
Number of permutations used.
Mantel, N. (1963). Chi-square tests with one degree of freedom: Extensions of the Mantel-Haenszel procedure. Journal of the American Statistical Association, 58(303), 690-700. doi:10.1080/01621459.1963.10500879
Hemerik, J., & Goeman, J. (2018). Exact testing with random permutations. TEST, 27(4), 811-825. doi:10.1007/s11749-017-0571-1
set.seed(1) n <- 60 group <- rep(c("Reference", "Focal"), each = n / 2) item <- rbinom(n, 1, 0.5) total <- rowSums(replicate(5, rbinom(n, 1, 0.5))) exact_mantel_dif(item, group, total, n_perm = 500)set.seed(1) n <- 60 group <- rep(c("Reference", "Focal"), each = n / 2) item <- rbinom(n, 1, 0.5) total <- rowSums(replicate(5, rbinom(n, 1, 0.5))) exact_mantel_dif(item, group, total, n_perm = 500)
Runs the exact/permutation Mantel test (see exact_mantel_dif)
on every column of a response matrix. Dichotomous (0/1) and
polytomous (0..C-1) items may be freely mixed within the same
matrix; item type is auto-detected per column.
run_dif_screening( response_matrix, group, n_perm = 5000, seed = 123, p_adjust_method = "none" )run_dif_screening( response_matrix, group, n_perm = 5000, seed = 123, p_adjust_method = "none" )
response_matrix |
A numeric matrix or data frame of item responses: rows are examinees, columns are items. |
group |
Vector of group membership (2 levels), of the same
length as |
n_perm |
Integer; number of permutations per item (default 5000). |
seed |
Integer; base random seed (default 123). Each item uses
|
p_adjust_method |
Character; multiple-testing correction method
passed to |
A data frame with one row per item; see
exact_mantel_dif for column descriptions. An
additional item column identifies each item (from
colnames(response_matrix) if available), and, when
p_adjust_method != "none", a p_exact_adjusted column
is added and used to update the classification column.
set.seed(42) n <- 80 group <- rep(c("Reference", "Focal"), each = n / 2) # 3 dichotomous items, 2 polytomous items (0-3) resp <- data.frame( Item1 = rbinom(n, 1, 0.5), Item2 = rbinom(n, 1, 0.5), Item3 = rbinom(n, 1, 0.5), Item4 = sample(0:3, n, replace = TRUE), Item5 = sample(0:3, n, replace = TRUE) ) run_dif_screening(resp, group, n_perm = 500, p_adjust_method = "BH")set.seed(42) n <- 80 group <- rep(c("Reference", "Focal"), each = n / 2) # 3 dichotomous items, 2 polytomous items (0-3) resp <- data.frame( Item1 = rbinom(n, 1, 0.5), Item2 = rbinom(n, 1, 0.5), Item3 = rbinom(n, 1, 0.5), Item4 = sample(0:3, n, replace = TRUE), Item5 = sample(0:3, n, replace = TRUE) ) run_dif_screening(resp, group, n_perm = 500, p_adjust_method = "BH")