
Expand Ordinal Data into Stacked Binary Comparisons for Adjacent-Category Logit Regression (C++ Backend)
Source:R/RcppExports.R
expand_adjacent_category_data_cpp.RdReshapes an ordinal response y (levels \(1, \dots, K\)) into the stacked
binary-outcome, per-cut-stratified form required to fit an adjacent-category logit
model as a single conditional (stratified) logistic regression, so the package's
existing binary/conditional-logit fitting backends can be reused unchanged for
ordinal adjacent-category models rather than needing a bespoke ordinal solver.
Arguments
- y
Integer vector of length \(n\): each subject's ordinal category label, in
1:K.- w
Integer vector of length \(n\): a covariate (typically treatment assignment) carried through unchanged into each stacked row for that subject.
- strata
Integer vector of length \(n\): positive-integer stratum/block labels;
max(strata)is used as the per-cut stratum-ID offset (see Details).- K
Integer; the number of ordinal categories (so there are
K - 1adjacent-category cuts).
Value
A list with components y (stacked 0/1 binary outcome), w
(stacked covariate, passed through unchanged), and strata (stacked
combined stratum-by-cut ID); all three are integer vectors of the same,
generally-longer-than-\(n\) length (each subject contributes 0, 1, or 2
stacked rows depending on their observed category).
Details
Model. The adjacent-category logit model compares each pair of consecutive categories \(j\) and \(j+1\) (\(j = 1, \dots, K-1\)) via $$\log\frac{\Pr(Y = j+1 \mid Y \in \{j, j+1\})}{\Pr(Y = j \mid Y \in \{j, j+1\})} = \alpha_j + \beta^\top x,$$ i.e. a logistic model for "category \(j+1\) vs. category \(j\)" fit using only the subjects actually observed in one of those two categories, with a cut-specific intercept \(\alpha_j\) and covariate effects \(\beta\) constrained equal across all \(K-1\) cuts (the proportional/parallel adjacent-category assumption). This differs from the cumulative-logit (proportional-odds) model, which instead compares \(Y \le j\) vs. \(Y > j\) using every subject at every cut.
Expansion mechanics. For each subject \(i\) and each cut
\(j = 1, \dots, K-1\) (n_alpha = K - 1), a stacked row is emitted
only if y[i] equals \(j\) or \(j+1\); subjects at any other
level contribute nothing to that cut's comparison (so each subject contributes to
at most 2 of the \(K-1\) cuts: the ones immediately adjacent to their observed
level, and exactly 1 cut if at an extreme level). The stacked binary outcome is
1 if y[i] == j + 1 (upper category) and 0 if
y[i] == j (lower category). The stacked stratum ID is
strata[i] + (j - 1) * num_strata (where num_strata = max(strata)),
i.e. the original stratum crossed with the cut index \(j\): fitting a
conditional logistic regression stratified on this combined ID and pooling all
stacked rows together estimates a single shared treatment coefficient
\(\beta\) across all cuts, while allowing each (original stratum, cut)
combination to absorb its own nuisance intercept via strata conditioning (the same
stratified-conditional-logit trick used elsewhere in the package, e.g. for
continuation-ratio models via expand_continuation_ratio_data_cpp()).
Input conventions. y must take integer values in
1:K (1-based category labels); w is typically the treatment
indicator/covariate to estimate a coefficient for, passed through unchanged per
stacked row (not itself expanded/transformed); strata must be positive
integers with max(strata) == num_strata (no gaps assumed beyond that
maximum, since combined stratum IDs are computed by simple integer arithmetic on
num_strata, not by re-indexing distinct values). No input validation is
performed at this layer (no range/type checks on y/strata); passing
out-of-range values silently produces incorrect stratum IDs or drops rows rather
than erroring.
See also
expand_continuation_ratio_data_cpp() for the analogous expansion
used by continuation-ratio ordinal models.
Ordinal regression for
orientation; analogous Python API:
statsmodels discrete
models (no direct adjacent-category equivalent; the closest analog is fitting
the expanded data as a conditional/grouped logit).