odds_summary: Turning Probabilistic Estimates into Clear, Decision-Ready Insights

[This article was first published on R-Blog on Data modelling to develop ..., and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Introduction

Model tuning and estimation has evolved from simple extrapolation to sophisticated probabilistic modeling frameworks. In contemporary data science, decision-makers require more than estimates, the need for clear statements about likelihood, risk, and uncertainty are critical to correct decision-making. However, despite the advances in predictive modeling, there is a persistent limitation of making quick and robust decisions from the estimated probabilities. The estimates are often not meaningfully interpreted. This is where the odds_summary function becomes strategically important. It converts probabilistic outputs into structured summaries that directly support:

• decision-making

• risk communication

• model validation

• reproducible research

In practical terms, it turns numbers into evidence.

The function is implemented as follows:

odds_summary(model)

where:

model An R object of estimates from models covered. For now only glm, multimon and polr models are covered.

Implement the function

library(Dyn4cast)
library(tidyverse)

Ordered Logistic Model

library(MASS)
options(contrasts = c("contr.treatment", "contr.poly"))
house.plr <- polr(Sat ~ Infl + Type + Cont, weights = Freq, data = housing)
modelsummary::datasummary_df(odds_summary(house.plr))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
InflMedium 0.57 0.10 5.41 0.00 0.566*** 1.76 76.19 1.762*** 1.44 2.16
InflHigh 1.29 0.13 10.14 0.00 1.289*** 3.63 262.85 3.628*** 2.83 4.66
TypeApartment -0.57 0.12 -4.80 0.00 -0.572*** 0.56 -43.58 0.564*** 0.45 0.71
TypeAtrium -0.37 0.16 -2.36 0.02 -0.366* 0.69 -30.66 0.693* 0.51 0.94
TypeTerrace -1.09 0.15 -7.20 0.00 -1.091*** 0.34 -66.41 0.336*** 0.25 0.45
ContHigh 0.36 0.10 3.77 0.00 0.36*** 1.43 43.37 1.434*** 1.19 1.73
Low|Medium -0.50 0.12 -3.97 0.00 -0.496*** 0.61 -39.11 0.609*** -0.74 -0.25
Medium|High 0.69 0.13 5.50 0.00 0.691*** 2.00 99.51 1.995*** 0.44 0.94

glm models

counts <- c(18, 17, 15, 20, 10, 20, 25, 13, 12)
outcome <- gl(3, 1, 9)
treatment <- gl(3, 3)
ddc <- data.frame(treatment, outcome, counts) # showing data
glm.D93 <- glm(counts ~ ., data = ddc, family = poisson())
modelsummary::datasummary_df(odds_summary(glm.D93))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
(Intercept) 3.04 0.17 17.81 0.00 3.045*** 21.00 2000.00 21*** 14.82 28.98
treatment2 0.00 0.20 0.00 1.00 0 1.00 0.00 1 0.67 1.48
treatment3 0.00 0.20 0.00 1.00 0 1.00 0.00 1 0.67 1.48
outcome2 -0.45 0.20 -2.25 0.02 -0.454* 0.63 -36.51 0.635* 0.42 0.94
outcome3 -0.29 0.19 -1.52 0.13 -0.293 0.75 -25.40 0.746 0.51 1.09
anorex.1 <- glm(Postwt ~ Prewt + Treat + offset(Prewt),
family = gaussian, data = anorexia
)
modelsummary::datasummary_df(odds_summary(anorex.1))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
(Intercept) 49.77 13.39 3.72 0.00 49.771*** 4.123994e+21 4.123994e+23 4.12399379732274e+21*** 1.647835e+10 1.032101e+33
Prewt -0.57 0.16 -3.51 0.00 -0.566*** 5.700000e-01 -4.319000e+01 0.568*** 4.100000e-01 7.800000e-01
TreatCont -4.10 1.89 -2.16 0.03 -4.097* 2.000000e-02 -9.834000e+01 0.017* 0.000000e+00 6.800000e-01
TreatFT 4.56 2.13 2.14 0.04 4.563* 9.588000e+01 9.487670e+03 95.877* 1.460000e+00 6.274970e+03
clotting <- data.frame(
u = c(5, 10, 15, 20, 30, 40, 60, 80, 100),
lot1 = c(118, 58, 42, 35, 27, 25, 21, 19, 18),
lot2 = c(69, 35, 26, 21, 18, 16, 13, 12, 12)
)
lot1 <- glm(lot1 ~ log(u), data = clotting, family = Gamma)
modelsummary::datasummary_df(odds_summary(lot1))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
(Intercept) -0.02 0.00 -17.85 0.00 -0.017*** 0.98 -1.64 0.984*** 0.98 0.99
log(u) 0.02 0.00 36.97 0.00 0.015*** 1.02 1.55 1.015*** 1.01 1.02
lot2 <- glm(lot2 ~ log(u), data = clotting, family = Gamma)
modelsummary::datasummary_df(odds_summary(lot2))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
(Intercept) -0.02 0.00 -18.02 0.00 -0.024*** 0.98 -2.36 0.976*** 0.97 0.98
log(u) 0.02 0.00 40.92 0.00 0.024*** 1.02 2.39 1.024*** 1.02 1.03
x <- rnorm(100)
y <- rpois(100, exp(1 + x))
lm2 <- glm(y ~ x, family = quasi(variance = "mu", link = "log"))
modelsummary::datasummary_df(odds_summary(lm2))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
(Intercept) 0.92 0.06 14.45 0.00 0.915*** 2.50 149.71 2.497*** 2.20 2.82
x 1.05 0.04 29.75 0.00 1.053*** 2.87 186.74 2.867*** 2.67 3.07
lm3 <- glm(y ~ x, family = poisson)
modelsummary::datasummary_df(odds_summary(lm3))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
(Intercept) 0.92 0.07 13.56 0.00 0.915*** 2.50 149.71 2.497*** 2.18 2.84
x 1.05 0.04 27.92 0.00 1.053*** 2.87 186.74 2.867*** 2.66 3.09

mlogit models

library(mlogit)
data("Fishing", package = "mlogit")
Fish <- dfidx(Fishing, varying = 2:9, shape = "wide", choice = "mode")
## a pure "conditional" model
mml <- mlogit(mode ~ price + catch, data = Fish)
modelsummary::datasummary_df(odds_summary(mml))
Variables Coefficient Std Error t value p value Coef Sig Odds_ratio % Odds Sig CI_lower CI_upper
(Intercept):boat 0.87 0.11 7.64 0.00 0.871*** 2.39 139.02 2.39*** 1.91 2.99
(Intercept):charter 1.50 0.13 11.28 0.00 1.499*** 4.48 347.67 4.477*** 3.45 5.81
(Intercept):pier 0.31 0.11 2.68 0.01 0.307** 1.36 35.94 1.359** 1.09 1.70
price -0.02 0.00 -14.54 0.00 -0.025*** 0.98 -2.45 0.976*** 0.97 0.98
catch 0.38 0.11 3.43 0.00 0.377*** 1.46 45.82 1.458*** 1.18 1.81

Multinomial Logistic model

For multinomial logistic regression, each of the measure is a data.frame, so the summary is a list of data frames. The summary is for each of the levels of the dependent variable.

library(nnet)
tinom <- multinom(Species ~ Petal.Length + Petal.Width + Sepal.Length
+ Sepal.Width, trace = FALSE, data = iris)
odds_summary(tinom)
$coefficient
Variables versicolor virginica
1 (Intercept) 18.690374 -23.836276
2 Petal.Length 14.244770 23.659779
3 Petal.Width -3.097684 15.135301
4 Sepal.Length -5.458424 -7.923634
5 Sepal.Width -8.707401 -15.370769
$t_value
versicolor virginica
1 0.53445109 -0.66644166
2 0.23665670 0.39128070
3 -0.06809815 0.32950063
4 -0.06072192 -0.08812701
5 -0.05544649 -0.09782845
$Odds_ratio
Variables versicolor virginica
1 (Intercept) 1.309563e+08 4.446690e-11
2 Petal.Length 1.536120e+06 1.885001e+10
3 Petal.Width 4.515366e-02 3.742635e+06
4 Sepal.Length 4.260265e-03 3.620841e-04
5 Sepal.Width 1.653575e-04 2.111348e-07
$Percent_odds
Variables versicolor virginica
1 (Intercept) 1.309563e+10 -1.000000e+02
2 Petal.Length 1.536119e+08 1.885001e+12
3 Petal.Width -9.548463e+01 3.742634e+08
4 Sepal.Length -9.957397e+01 -9.996379e+01
5 Sepal.Width -9.998346e+01 -9.999998e+01
$Coef_sig
versicolor virginica
1 18.69 -23.836
2 14.245 23.66
3 -3.098 15.135
4 -5.458 -7.924
5 -8.707 -15.371
$Odds_sig
versicolor virginica
1 130956302.531 0
2 1536119.713 18850009278.36
3 0.045 3742635.304
4 0.004 0
5 0 0
$p_value
versicolor virginica
1 0.5930295 0.5051288
2 0.8129231 0.6955898
3 0.9457075 0.7417773
4 0.9515807 0.9297757
5 0.9557828 0.9220685
$Confident_interval
Variables Lower versicolor Upper versicolor Lower virginica
1 (Intercept) -49.85184 87.23259 -93.93730
2 Petal.Length -103.72880 132.21834 -94.85441
3 Petal.Width -92.25354 86.05818 -74.89380
4 Sepal.Length -181.64381 170.72696 -184.14699
5 Sepal.Width -316.50312 299.08832 -323.31956
Upper virginica
1 46.26475
2 142.17397
3 105.16440
4 168.29972
5 292.57802

Conclusion

The odds_summary function represents a critical advancement in the practical interpretation of probabilistic estimates within the Dyn4cast environment. Its significance lies not in computation alone, but in converting statistical output into actionable knowledge. In econometric modelling systems, prediction without interpretation is incomplete. The odds_summary function closes that gap.

Attrition

cite this article as:
Nmadu J (2025). odds_summary: Turning Probabilistic Estimates into Clear, Decision-Ready Insights. https://www.jobnmadu.com/r-blog/.
To cite package 'Dyn4cast' in publications use:
Nmadu J (2025). _Dyn4cast: Dynamic Modeling and Machine Learning
Environment_. R package version 11.11.26,
<https://github.com/JobNmadu/Dyn4cast>.
A BibTeX entry for LaTeX users is
@Manual{,
title = {_Dyn4cast: Dynamic Modeling and Machine Learning Environment_},
author = {Job Nmadu},
year = {2025},
note = {R package version 11.11.26},
url = {https://github.com/JobNmadu/Dyn4cast},
}

Welcome to Data Science and Machine Learning!

To leave a comment for the author, please follow the link and comment on their blog: R-Blog on Data modelling to develop ....

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)