# Ordinal regression

**URL:** https://discourse.pumas.ai/t/ordinal-regression/1388
**Category:** How-to
**Created:** [March 12, 2026, 9:29pm UTC](https://discourse.pumas.ai/t/ordinal-regression/1388 "2026-03-12T21:29:54Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![MathangiCTM](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.pumas.ai/mathangictm/32/142_2.png) [@MathangiCTM](https://discourse.pumas.ai/u/MathangiCTM)
#### Post date: [March 12, 2026, 9:29pm UTC](https://discourse.pumas.ai/t/ordinal-regression/1388/1 "2026-03-12T21:29:54Z")

</div>

Hi help,

I am trying to run the example on ordinal regression from here: [Ordinal Regression](https://tutorials.pumas.ai/html/discrete/02-OrdinalRegression.html)

When I use the manual way of writing the ordinal model using `Categorical`, I get the below error.

Could you please help? The model is exactly as in the tutorials.

```auto
## Manual way - Using Categorical
ordinal_model2 = @model begin
    @param begin
        α ∈ VectorDomain(; init = [0.001, 0.002, 0.003])
        βRx ∈ RealDomain()
    end

    @covariates begin
        isRx
    end

    @pre begin
        ϕ = α .- isRx * βRx

        # cut points for >= 1, >=2 and >=3
        γ = logistic.(ϕ)

        # probabilities for PainScore =1, =2, =3 and =4
        p₄ = 1.0 - γ[3]
        p₃ = γ[3] - γ[2]
        p₂ = γ[2] - γ[1]
        p₁ = γ[1]
    end

    @derived begin
        PainScore ~ @. Categorical(p₁, p₂, p₃, p₄)
    end
end
## model fit
pk_painrelief_categorical_fit = fit(
    ordinal_model2,
    pk_painrelief_pop,
    (; init_params(ordinal_model2)..., α = init_intercepts),
    NaivePooled(),
)

```

Thanks.

> ERROR: UndefVarError: `Categorical` not defined in `Main`  
> Hint: It looks like two or more modules export different bindings with this name, resulting in ambiguity. Try explicitly importing it from a particular module, or qualifying the name with the module it should come from.  
> Hint: a global variable of this name also exists in Distributions.  
> Hint: a global variable of this name also exists in Pumas.  
> Hint: a global variable of this name also exists in Makie.  
> Hint: a global variable of this name also exists in CairoMakie.  
> Stacktrace:  
> [1] (::var"#22#27")(\_pre::Returns{…}, \_sol::Pumas.NullDESolution{…}, \_t::Vector{…}, \_subject::Subject{…}, \_param@NamedTuple:@NamedTuple{…}, \_random@NamedTuple:@NamedTuple{})  
> @ Main .\none:2505  
> [2] DerivedObj  
> @ .\none:2403 [inlined]  
> [3] #\_derived#394  
> @ .\none:1960 [inlined]  
> [4] \_derived  
> @ .\none:1904 [inlined]  
> [5] \_conditional\_nll(m::PumasModel{…}, subject::Subject{…@NamedTuple, param::@NamedTuple{…}, @NamedTupleandeffs::@NamedTuple{}; diffeq@NamedTupleoptions::@NamedTuple{…})  
> @ Pumas .\none:1456  
> [6] \_conditional\_nll  
> @ .\none:1449 [inlined]  
> [7] \_\_marginal\_nll  
> @ .\none:1833 [inlined]  
> [8] #\_marginal\_nll#559  
> @ .\none:1801 [inlined]  
> [9] \_marginal\_nll  
> @ .\none:1771 [inlined]  
> [10] \_marginal\_nll\_vparam  
> @ .\none:3052 [inlined]  
> [11] FixTail  
> @ C:\Users\mgopalakrishnan.julia\packages\DifferentiationInterface\M8gIf\src\utils\context.jl:172 [inlined]  
> [12] vector\_mode\_dual\_eval!  
> @ C:\Users\mgopalakrishnan.julia\packages\ForwardDiff\egQMG\src\apiutils.jl:24 [inlined]  
> [13] vector\_mode\_gradient!(result::DiffResults.MutableDiffResult{…}, f::DifferentiationInterface.FixTail{…}, x::Vector{…}, cfg::ForwardDiff.GradientConfig{…})  
> @ ForwardDiff C:\Users\mgopalakrishnan.julia\packages\ForwardDiff\egQMG\src\gradient.jl:105  
> [14] gradient!  
> @ C:\Users\mgopalakrishnan.julia\packages\ForwardDiff\egQMG\src\gradient.jl:39 [inlined]  
> [15] value\_and\_gradient!  
> @ C:\Users\mgopalakrishnan.julia\packages\DifferentiationInterface\M8gIf\ext\DifferentiationInterfaceForwardDiffExt\onearg.jl:398 [inlined]  
> [16] value\_and\_gradient!  
> @ C:\Users\mgopalakrishnan.julia\packages\DifferentiationInterface\M8gIf\ext\DifferentiationInterfaceForwardDiffExt\onearg.jl:305 [inlined]  
> [17] #\_evaluate\_marginal\_nll\_gradient!#632  
> @ .\none:3086 [inlined]  
> [18] \_evaluate\_marginal\_nll\_gradient!  
> @ .\none:3062 [inlined]  
> [19] \_evaluate\_marginal\_nll\_gradient!(g::Vector@NamedTuple…}, model::PumasModel{…}, population::Vector{…}, param::@NamedTuple{…}, vparam::Vector{…}, vvrandeffsorth::Vector{…}, approx::NaivePooled, tr@NamedTuple::TransformVariables.TransformTuple{…}, diffeq\_options::@NamedTuple{…}, ::EnsembleSerial; update\_ebes::Bool)  
> @ Pumas .\none:4771  
> [20] \_evaluate\_marginal\_nll\_gradient!  
> @ .\none:4749 [inlined]  
> [21] \_evaluate\_marginal\_nll\_gradient!(g::Vector@NamedTuple…}, model::PumasModel{…}, population::Vector{…}, param::@NamedTuple{…}, vparam::Vector{…}, vvrandeffsorth::Vector{…}, approx::NaivePooled, tr@NamedTuple::TransformVariables.TransformTuple{…}, diffeq\_options::@NamedTuple{…}, ::EnsembleThreads; update\_ebes::Bool)  
> @ Pumas .\none:4905  
> [22] \_evaluate\_marginal\_nll\_gradient!  
> @ .\none:4885 [inlined]  
> [23] #\_evaluate\_objective\_gradient!#718  
> @ .\none:6433 [inlined]  
> [24] \_evaluate\_objective\_gradient!  
> @ .\none:6420 [inlined]  
> [25] (::Pumas.var"#722#728"{…})(f::Float64, g::Vector{…}, \_vparam::Vector{…})  
> @ Pumas .\none:6590  
> [26] (::Pumas.OptimSafeFGFunction{true, Pumas.var"#722#728"{…}})(F::Float64, g::Vector{Float64}, x::Vector{Float64})  
> @ Pumas .\none:6175  
> [27] (::NLSolversBase.var"#83#87"{Pumas.OptimSafeFGFunction{…}, Float64})(G::Vector{Float64}, x::Vector{Float64})  
> @ NLSolversBase C:\Users\mgopalakrishnan.julia\packages\NLSolversBase\gOqwS\src\objective\_types\incomplete.jl:108  
> [28] value\_gradient!!(obj::NLSolversBase.OnceDifferentiable{Float64, Vector{…}, Float64, Vector{…}}, x::Vector{Float64})  
> @ NLSolversBase C:\Users\mgopalakrishnan.julia\packages\NLSolversBase\gOqwS\src\interface.jl:82  
> @ NLSolversBase C:\Users\mgopalakrishnan.julia\packages\NLSolversBase\gOqwS\src\interface.jl:82  
> [30] initial\_state(method::Optim.BFGS{…}, ::Optim.Options{…}, d::NLSolversBase.OnceDifferentiable{…}, x0::Vector{…})  
> @ Optim C:\Users\mgopalakrishnan.julia\packages\Optim\mv9zc\src\multivariate\solvers\first\_order\bfgs.jl:108  
> [31] (::Pumas.DefaultOptimizeFN{…})(cost::NLSolversBase.OnceDifferentiable{…}, p::Vector{…}, pumas\_callback::Nothing, verbose::Bool, optim\_cache::Nothing, check\_zero\_gradient::Pumas.var"#724#730"{…})  
> @ Pumas .\none:4501  
> [32] \_fit(m::PumasModel{…}, population::Vector{…}, vparam::Vector{…}, approx::NaivePooled, ensemblealg::En@NamedTupleembleThreads, optimize\_fn::Pumas.DefaultOptimizeFN{…}, checkidentification::Bool, diffeq\_options::@NamedTuple{…}, init\_vrandeffsorth::Vector{…}, verbose::Bool, ignore\_numerical\_error::Bool, opti@NamedTuple\_state::Nothing)  
> @ Pumas .\none:6754  
> [33] fit(model::PumasModel{…}, population::Vecto@NamedTuple{…}, param::@NamedTuple{…}, approx::NaivePooled; init\_randeffs::Nothing, optim\_alg::Nothing, optim\_options::@NamedTuple{}, optimize\_@NamedTuplen::Nothing, constantcoef::Tuple{}, omegas::Tuple{}, ensemblealg::EnsembleThreads, diffeq\_options::@NamedTuple{}, checkidentification::Bool, verbose::Bool, ignore\_numer@NamedTuplecal\_error::Bool)  
> @ Pumas .\none:6115  
> [34] fit(model::PumasModel{…}, population::Vector{…}, param::@NamedTuple{…}, approx::NaivePooled)  
> @ Pumas .\none:6015  
> [35] top-level scope

---

<div class="post-metadata">

### Author: ![MathangiCTM](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.pumas.ai/mathangictm/32/142_2.png) [@MathangiCTM](https://discourse.pumas.ai/u/MathangiCTM)
#### Post date: [March 12, 2026, 9:43pm UTC](https://discourse.pumas.ai/t/ordinal-regression/1388/2 "2026-03-12T21:43:11Z")

</div>

Nevermind. When I explicitly specified the module as hinted in the error message, I was able to run it.

Thanks.

> @derived begin  
> PainScore ~ @. Pumas.Categorical(p₁, p₂, p₃, p₄)  
> end
