View source: R/conditional_infit.R
| RMitemInfit | R Documentation |
Computes conditional infit mean-square (MSQ) statistics for each item using
iarm::out_infit(), enriched with item locations relative to the sample
mean person location.
RMitemInfit(
data,
cutoff = NULL,
p_value = NULL,
correction = c("fwer", "fdr_bh", "fdr_by", "none"),
alpha = 0.05,
output = "kable",
sort,
statistic = "infit"
)
data |
A data.frame or matrix of item responses. Items must be scored
starting at 0 (non-negative integers). Missing values ( |
cutoff |
Optional. Default
|
p_value |
Logical or
With Up to and including version 1.1.1 the default was |
correction |
Character. Multiple-comparison correction applied across
items when |
alpha |
Numeric in (0, 1). Significance level for the |
output |
Character string controlling the return value. Either
|
sort |
Optional character string. When |
statistic |
Character string. Which conditional fit statistic the table
reports: |
Infit MSQ is a weighted fit statistic that emphasises deviations near the
item location. Values close to 1.0 indicate good fit. Values substantially
above 1.0 suggest underfit (unexpected responses), while values substantially
below 1.0 suggest overfit (overly predictable responses). The definition of
"substantially" depends on several factors such as sample size, and needs to
be determined by simulation using RMitemInfitCutoff. There is no general
rule-of-thumb value that is correct.
Conditional infit MSQ statistics are computed via iarm::out_infit(), which
uses the conditional distribution of the sufficient statistics (Müller, 2020).
Only complete cases (rows without any NA) are used in the conditional fit
calculation.
Item parameters are estimated by conditional maximum likelihood via
psychotools::pcmodel() (a dichotomous item is a 2-category PCM); the
conditional infit/outfit MSQ comes from iarm::out_infit() and is invariant
to the estimation engine. Per-item average locations are the means of the
CML thresholds, and the person-location reference is the mean of the Warm
WLE estimates.
Relative item location is defined as the item's average location minus the sample mean person location, providing a measure of item targeting.
The iarm package must be installed (it is in Suggests, not Imports).
Bootstrap p-values. When p_value = TRUE, each item's observed
infit (or outfit, per statistic) is compared against its simulated null
distribution (from cutoff$results). The per-item statistic is the residual studentised by
the bootstrap mean and SD – deliberately the empirical SD rather than the
Wilson-Hilferty / ZSTD transform, which is uninformative for conditional
MSQ (Müller, 2020). The marginal p-value is the two-sided Monte-Carlo
p-value (1 + #{|t*| >= |t|}) / (B + 1). For correction = "fwer" the
family-wise adjustment uses the Westfall-Young studentised-max step-down,
which exploits the bootstrap dependence among items and is more powerful
than Bonferroni/Holm (Ferreira, 2024); its validity rests on subset
pivotality. "fdr_bh"/"fdr_by" apply Benjamini-Hochberg / Benjamini-
Yekutieli instead. These are model-conditional, sample-size-sensitive
p-values and are reported alongside the simulated effect-size band, not in
place of it. p-values can be no smaller than 1 / (B + 1), and the
studentised-max (FWER) correction is liberal when the simulation is small
(the bootstrap mean/SD used for studentisation are then too noisy). At
least 1000 iterations in RMitemInfitCutoff() are recommended – in
simulations the family-wise error rate is then controlled at the nominal
level – and a warning is issued when the simulation is smaller. The
marginal p-values are well calibrated even at a few hundred iterations.
If output = "kable": a knitr_kable object (plain text table via
format = "pipe") with columns "Item", "Infit MSQ", and "Relative
location", and a caption showing the number of complete cases. When
cutoff is provided, columns "Infit low", "Infit high", and "Flagged"
are also included, and the caption notes the simulation-based cutoffs.
If output = "dataframe": a data.frame with columns Item,
Infit_MSQ, and Relative_location. When cutoff is provided, columns
Infit_low, Infit_high, and Flagged are also included (inserted
after Infit_MSQ, before Relative_location). Flagged is a character
column with values "overfit", "underfit", or "" (not the previous
logical). When p_value = TRUE, columns p_infit (marginal two-sided
p-value) and padj_infit (corrected p-value) are added and Flagged
reflects items with padj_infit < alpha (direction from Infit_MSQ
relative to 1).
With statistic = "outfit" the layout is identical and the column names
follow the statistic: Outfit_MSQ, Outfit_low, Outfit_high, p_outfit,
padj_outfit.
The marginal p-value controls the error rate of a single comparison: for
one item (or item pair) decided on in advance it is the relevant value. But
scanning all k comparisons and flagging whichever fall below alpha tests
k hypotheses at once, so the chance of at least one false flag inflates to
roughly 1 - (1 - \alpha)^k (e.g. about 34% for k = 8 at
alpha = 0.05) – even when every marginal p-value is correctly calibrated.
The corrected (adjusted) p-value controls this: correction = "fwer" bounds
the probability of any false flag (strict, lower power), while "fdr_bh" /
"fdr_by" bound the expected proportion of false flags among those raised
(a more lenient middle ground). Rule of thumb: use the marginal p-value for a
single pre-specified comparison, and a corrected p-value when screening the
whole table – the usual workflow.
Müller, M. (2020). Item fit statistics for Rasch analysis: Can we trust them? Journal of Statistical Distributions and Applications, 7(5). \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1186/s40488-020-00108-7")}
Ferreira, J. A. (2024). Methods of testing a 'small' or 'moderate' number of hypotheses simultaneously. Journal of Statistical Theory and Practice, 19(6). \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1007/s42519-024-00412-4")}
Westfall, P. H., & Young, S. S. (1993). Resampling-Based Multiple Testing. Wiley.
Johansson, M. (2026). Simulation-based cutoffs for conditional item fit in Rasch models: Iterations, multiplicity correction, and decision stability. PsyArXiv. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.31234/osf.io/7pqz4_v2")}
RMitemInfitCutoff
if (requireNamespace("iarm", quietly = TRUE)) {
# Simulate binary item response data (5 items, 40 persons)
set.seed(42)
sim_data <- as.data.frame(
matrix(sample(0:1, 40 * 5, replace = TRUE), nrow = 40, ncol = 5)
)
colnames(sim_data) <- paste0("Item", 1:5)
# Default kable output
RMitemInfit(sim_data)
# Sorted by infit MSQ descending
RMitemInfit(sim_data, sort = "infit")
# Return as data.frame for further processing
df <- RMitemInfit(sim_data, output = "dataframe")
# Simulation-based cutoffs (100 Monte-Carlo iterations)
if (requireNamespace("ggdist", quietly = TRUE)) {
cutoff_res <- RMitemInfitCutoff(sim_data, iterations = 100,
parallel = FALSE, seed = 42)
RMitemInfit(sim_data, cutoff = cutoff_res)
RMitemInfit(sim_data, cutoff = cutoff_res, output = "dataframe")
# Bootstrap p-values with family-wise (Westfall-Young) correction
# (use iterations >= 1000 in real analyses for stable p-values)
RMitemInfit(sim_data, cutoff = cutoff_res, p_value = TRUE,
output = "dataframe")
# The same for conditional outfit MSQ
RMitemInfit(sim_data, cutoff = cutoff_res, p_value = TRUE,
statistic = "outfit", output = "dataframe")
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.