Skip to contents

Compare two groups at an explicitly supplied numeric matching variable, using three nested proportional-odds models. This independent-Person sensitivity analysis does not estimate ability or fit an MFRM.

Usage

ordinal_logistic_table(
  data,
  person,
  target,
  score,
  group,
  matching,
  groups,
  categories,
  p_adjust = "holm"
)

Arguments

data

Long-format data with at most one row per Person and target.

person

Name of the independent Person identifier column.

target

Name of the item or other target identifier column.

score

Name of the ordered response column. Numeric, character or factor scores are accepted, with order declared through categories.

group

Name of the group column. Each Person belongs to one group.

matching

Name of one finite numeric matching column. Values may differ across targets. Missing scores or matching values are excluded together from all models for the affected target.

groups

Two distinct labels in reference, focal order.

categories

Distinct numeric or character category labels, in increasing response order. Factor labels are treated as character. Category spacing has no effect. Every declared category must occur in each target's complete data; otherwise that target is unavailable. Categories are never collapsed.

p_adjust

A stats::p.adjust() method, default "holm". The DIF comparison family comprises all three tests for every observed target, including unavailable tests. Proportional-odds diagnostics form a separate family of one test per target.

Value

A plain list containing table (three comparisons per target), models (three PO fits and, for ordinal responses, a diagnostic fit), coefficients (available models only), contrasts, proportional_odds, matching, cases, settings and notes. cases$Included denotes complete rows supplied to eligible models, not successful estimation or valid DIF inference. Precluded targets retain their counts and reasons. Save the full result with base::saveRDS() and individual tables with utils::write.csv(). No backend model objects or executable environments are retained.

Details

Requires the optional package ordinal. Maximum likelihood is computed by ordinal::clm() with a logit link and flexible thresholds. For each target, matching is centered at its pooled midrange and divided by its half-range: z = (matching - Center) / Scale. Group is coded 0 for reference and 1 for focal. M1 uses z, M2 uses z + g, and M3 uses z * g. All three use identical complete responses. The model is logit Pr(Y <= k) = threshold[k] - linear_predictor.

Uniform compares M2 to M1 (1 df), Nonuniform compares M3 to M2 (1 df), and Joint compares M3 to M1 (2 df). These are asymptotic likelihood-ratio tests. A uniform comparison assumes no interaction; its coefficient must not be interpreted as a constant group difference when an interaction matters. No automatic selection between these models or DIF/bias flag is made. NagelkerkeR2 is (1-exp(2*(LL0-LL)/N))/(1-exp(2*LL0/N)), where LL0 is the intercept-only multinomial log likelihood. DeltaNagelkerkeR2 subtracts the reduced model's value from the full model's value. This is not explained score variance or McKelvey–Zavoina R-squared; no universal effect-size cutoff is applied.

contrasts gives M3's reference/focal upper-tail odds ratio at the lower endpoint, midpoint and upper endpoint of the groups' overlapping matching ranges. Its log is -(beta_g + beta_z:g * z); a value above 1 favors higher reference scores. This applies to each category cut under proportional odds. These are point estimates, not simultaneous intervals. Fits use all complete responses, including those outside that overlap. Range overlap alone does not establish comparable distributions or adequate local support. Each group must have varying matching values and their ranges must overlap with positive width. The matching table retains the ranges and transformation.

For three or more categories, proportional_odds compares M3 with a model in which all three slopes may differ across cumulative category cuts (clm(y ~ 1, nominal = ~ z * g)). This global asymptotic LR diagnostic has 3 * (K - 2) df. It concerns equality across category cuts, whereas the nonuniform comparison concerns differences across matching values. They are different questions. The diagnostic is not applicable to binary responses. An unavailable or nonsignificant diagnostic does not certify proportional odds. Its p-value does not determine availability or change the primary comparisons.

models retains convergence codes, warnings, gradient, Hessian and Newton step diagnostics. A fit is unavailable if the backend reports nonconvergence or nonunique parameters, any coefficient is aliased/nonfinite, the Hessian's minimum eigenvalue is at most sqrt(.Machine$double.eps) * max(1, max_eigen), the maximum absolute gradient exceeds 1e-6, or the maximum absolute Newton step exceeds 1e-4 on the scaled parameterization. Backend warnings also make the fit unavailable. These conservative numerical checks detect common separation failures; they are not a general proof of finite ML existence. Likelihood decreases beyond 64 * .Machine$double.eps * max(1, abs(LL)) invalidate a comparison; smaller rounding errors are set to zero. No penalized estimator, collapsed categories or alternative inference is substituted.

Inference requires independent Persons within each target, a suitable linear matching relationship, finite identifiable parameters and adequate data for chi-squared approximations. Sparse categories and small samples can invalidate those approximations even when numerical checks pass. Duplicate Person-target rows, including missing-score duplicates, are rejected before exclusions. Renaming repeated ratings as Persons does not establish independence. Dependence across targets is compatible with Holm adjustment of valid individual p-values, but no dependence within targets is handled here.

Interpreting conditional group association as DIF additionally requires defensible matching, invariant anchors and comparable rater/task exposure. Use a justified common rating plan; this interface does not adjust for plan differences, matching error, clustered ratings or informative missingness. Total and rest scores need not define the same comparison. RSM/PCM's adjacent category logits do not generally imply cumulative proportional odds. Therefore agreement with analyze_dff() or mantel_haenszel_table() does not by itself establish robustness, and disagreement does not by itself establish DIF.

References

Rogers, H. J., & Swaminathan, H. (1993). A comparison of logistic regression and Mantel-Haenszel procedures for detecting differential item functioning. Applied Psychological Measurement, 17, 105–116. doi:10.1177/014662169301700201 .

Zumbo, B. D. (1999). A handbook on the theory and methods of differential item functioning (DIF): Logistic regression modeling as a unitary framework for binary and Likert-type (ordinal) item scores. Department of National Defense, Ottawa, pp. 23–32. Pseudo-R-squared definitions and thresholds in that handbook are not interchangeable.

Examples

if (requireNamespace("ordinal", quietly = TRUE)) {
  d <- expand.grid(Match = c(-1, 0, 1), Group = c("R", "F"),
                   Score = 0:2, Replicate = 1:5)
  d$Person <- paste0("P", seq_len(nrow(d)))
  d$Item <- "A"
  ol <- ordinal_logistic_table(d, "Person", "Item", "Score", "Group",
                               "Match", c("R", "F"), 0:2)
  ol$table
  ol$proportional_odds
}
#>   Target ChiSquared DF PValue    Status PAdjusted
#> 1      A          0  3      1 available         1