Home Accueil / Blog / Statistics Statistiques

Proportional odds in ordinal outcomes:
how to test it and what to do when it fails

Cotes proportionnelles dans les outcomes ordinaux :
comment le tester et quoi faire quand ça échoue

TL;DR

The proportional odds assumption underlies every cumulative logit model. Most analysts never test it. When it fails, which is common, the reported odds ratios are meaningless averages. This article explains the assumption, how to test it, and what models to use when it is violated.

Ce que dit la supposition des cotes proportionnelles

La supposition des cotes proportionnelles (aussi appelée supposition de régression parallèle) stipule que la relation entre chaque prédicteur et les log-odds d'être dans une catégorie plus élevée est la même à tous les seuils possibles de l'outcome. C'est une supposition forte. Pour de nombreux outcomes ordinaux cliniques et cosmétiques, elle est violée.

Pourquoi ça compte en pratique

Quand la supposition est vérifiée, le modèle logit cumulatif produit un seul odds ratio par prédicteur. Quand elle échoue, ce OR est une moyenne pondérée d'ORs spécifiques à chaque seuil qui peuvent pointer dans des directions opposées. Le rapporter comme s'il était une synthèse significative de l'effet traitement est trompeur.

Tester avec nominal_test et ordinal_test

library(ordinal)

model_clmm <- clmm(
  pain_nrs_ord ~ treatment + visit + (1 | subject_id),
  data = pain_data, link = "logit"
)

nominal_test(model_clmm)
ordinal_test(model_clmm)

Un p-valeur significative pour nominal_test signifie qu'au moins un terme dans votre modèle a un effet variant selon le seuil.

Quand ça échoue : cotes partiellement proportionnelles

Le modèle à cotes partiellement proportionnelles permet à certains prédicteurs d'avoir des effets variant selon le seuil tandis que d'autres maintiennent la contrainte.

model_ppo <- clm(
  pain_nrs_ord ~ visit,
  nominal = ~ treatment,  # treatment obtient des OR spécifiques par seuil
  data = pain_data, link = "logit"
)
summary(model_ppo)

Rapporter correctement les outcomes ordinaux

Votre plan d'analyse doit spécifier le modèle ordinal primaire, le test de cotes proportionnelles comme diagnostic planifié, et l'analyse de sensibilité à exécuter si la supposition échoue. Dans la section résultats, rapportez si la supposition a été vérifiée. Ne changez pas silencieusement de modèle sans documenter la décision.


À retenir

La supposition des cotes proportionnelles est une contrainte testable, pas une garantie. Testez-la toujours. Quand elle échoue légèrement, le modèle à cotes partiellement proportionnelles donne des estimations spécifiques par seuil. Quand elle échoue vraiment, reconsidérez si la régression ordinale est le bon outil.

What the proportional odds assumption says

An ordinal outcome is a categorical variable with a natural order: pain NRS 0-10, tumor necrosis score 0-4, skin roughness 0-3. The proportional odds assumption (also called the parallel regression assumption) states that the relationship between each predictor and the log odds of being in a higher vs lower category is the same across all possible cut-points of the outcome.

Concretely: if treatment reduces the log-odds of being in a higher pain category (vs 0-5) by 0.6, the assumption says it also reduces the log-odds of being in category 8-10 (vs 0-7) by 0.6. The predictor's effect is assumed constant across all thresholds.

This is a strong assumption. For many clinical and cosmetic ordinal outcomes, it is violated.

Why it matters in practice

When the proportional odds assumption holds, the cumulative logit model (polr in R, clm/clmm in the ordinal package) produces a single odds ratio per predictor that summarizes the treatment effect across the entire scale. This is elegant and interpretable.

When it fails, the single OR is a weighted average of threshold-specific ORs that may point in opposite directions. Reporting it as if it were a meaningful summary of the treatment effect is misleading.

Testing with nominal_test and ordinal_test

library(ordinal)

# Fit cumulative logit mixed model
model_clmm <- clmm(
  pain_nrs_ord ~ treatment + visit + (1 | subject_id),
  data = pain_data,
  link = "logit"
)

# Test proportional odds assumption
# nominal_test: tests if any predictor has non-proportional effects
# ordinal_test: tests if the ordinal structure adds value over nominal

nominal_test(model_clmm)
# Significant p-value for a term = that term violates proportional odds

ordinal_test(model_clmm)

A significant result for nominal_test means at least one term in your model has a threshold-varying effect. The column for each term tells you which predictor is causing the violation.

Visual diagnostics: the cumulative logit plot

library(MASS)

# Fit with polr for visual diagnostics
model_polr <- polr(
  pain_nrs_ord ~ treatment + visit,
  data = pain_data,
  method = "logistic"
)

# Brant test (polr version of proportional odds test)
library(brant)
brant(model_polr)

The Brant test output shows a chi-squared statistic and p-value for each predictor and an omnibus test. For the visual: plot the log-odds of being above each threshold against your predictor. If proportional odds holds, these lines should be parallel. If they fan out or cross, the assumption is violated.

When it fails: partial proportional odds

The partial proportional odds model allows some predictors to have threshold-varying effects while others maintain the proportional odds constraint. In R, this is implemented via the nominal argument in clm:

# treatment violates PO assumption; visit does not
model_ppo <- clm(
  pain_nrs_ord ~ visit,
  nominal    = ~ treatment,   # treatment gets threshold-specific ORs
  data       = pain_data,
  link       = "logit"
)

summary(model_ppo)
# treatment now has K-1 separate estimates (one per threshold)

This model is more flexible and better captures the true relationship. The cost is interpretability: you now have multiple effect estimates for treatment, one per threshold. Report them all in the results section, not just the one that looks best.

When it fails badly: multinomial logistic regression

If proportional odds fails for most predictors, the ordinal structure is not adding value and you should consider a fully nominal model:

library(nnet)

model_mult <- multinom(
  pain_nrs_ord ~ treatment + visit,
  data = pain_data
)

# This estimates K-1 sets of coefficients (one per non-reference category)
# Interpretation is harder but makes no structural assumptions

Multinomial regression is appropriate when the ordinal structure does not apply or when the PO assumption is badly violated across most predictors. The trade-off: you lose statistical efficiency and interpretability.

Reporting ordinal outcomes correctly

Regardless of which model you use, your analysis plan should specify:

  • The primary ordinal model (CLMM with proportional odds)
  • The proportional odds test (nominal_test or Brant) as a planned diagnostic
  • The sensitivity analysis to run if assumption fails (partial PO or multinomial)

In the results section, report whether the assumption held. If it failed and you switched to a sensitivity model, explain what changed and how it affects interpretation. Do not silently switch models without documenting the decision.


Key takeaway

The proportional odds assumption is a testable constraint, not a guarantee. Always test it. When it fails mildly, the partial proportional odds model gives you threshold-specific estimates. When it fails badly, reconsider whether ordinal regression is the right tool for your data.

AM

Aslane Mortreau

Freelance Data & AI specialist working with pharmaceutical, biotech, and cosmetic R&D teams. Statistical modeling, analytical pipelines, and custom applications.

Spécialiste Data & IA freelance travaillant avec des équipes R&D pharmaceutiques, biotech et cosmétiques. Modélisation statistique, pipelines analytiques et applications sur mesure.