*! version 1.0.1 02aug2026

Title

riskcalplot -- Plot observed and model-predicted risks across values of discrete clinical scores

Syntax

riskcalplot
endpoint score1
[score2 score3 score4 score5]
[if] [in]
,
model(model_list)
[options]

endpoint must be a numeric binary variable coded 0 and 1.
Each score must be numeric. One endpoint and one to five score variables
may be specified.

Model
model(model_list) specify logit or log for each score; required

Confidence intervals
noci suppress confidence intervals for observed risks

level(#) set the confidence level; default is the current set level

Markers
marker(msymbol) use the specified marker symbol for every score

Fitted-risk lines
plot1opts(line_options) modify the fitted-risk line for score 1

plot2opts(line_options) modify the fitted-risk line for score 2

plot3opts(line_options) modify the fitted-risk line for score 3

plot4opts(line_options) modify the fitted-risk line for score 4

plot5opts(line_options) modify the fitted-risk line for score 5

Confidence-interval layers
ci1opts(rcap_options) modify confidence intervals for score 1

ci2opts(rcap_options) modify confidence intervals for score 2

ci3opts(rcap_options) modify confidence intervals for score 3

ci4opts(rcap_options) modify confidence intervals for score 4

ci5opts(rcap_options) modify confidence intervals for score 5

Observed-risk markers
scatter1opts(scatter_options) modify observed-risk markers for score 1

scatter2opts(scatter_options) modify observed-risk markers for score 2

scatter3opts(scatter_options) modify observed-risk markers for score 3

scatter4opts(scatter_options) modify observed-risk markers for score 4

scatter5opts(scatter_options) modify observed-risk markers for score 5

Statistics
nostat suppress displayed performance statistics

statopts(note_options) modify the graph note containing statistics for score 1

Graph
twoway_options specify standard twoway graph options

Description

riskcalplot displays observed event risks and model-predicted risks
across the distinct values of one to five discrete clinical scores.

For each score value, the observed risk is the proportion of observations
with endpoint=1. Marker size is proportional to the number of
observations at that score value.

Unless noci is specified, each observed risk is accompanied by an
exact Clopper-Pearson binomial confidence interval. The confidence level is
controlled by level().

A separate regression model is fitted for each score. model(logit)
fits a logistic risk function. model(log) fits a modified Poisson
model with a log link and robust standard errors.

The command uses a common complete-case analysis sample containing
nonmissing values for the endpoint and every score specified in the
command.

By default, the legend is placed in the upper-left corner within the plot
region and is arranged vertically. For each score, legend entries are
ordered as follows:

Observed risk

Confidence interval

Fitted risk

When noci is specified, the confidence-interval entry is omitted.

By default, apparent performance statistics are displayed in the Results
window. Statistics for the first score are also placed in a graph note.
Statistics for every score are stored in r(stats).

Options

Model

model(model_list) specifies the model used to estimate predicted
risks. This option is required. The permitted model names are logit
and log.

If one model is specified, that model is applied to every score.

If more than one model is specified, the number and order of models must
match the number and order of score variables.

model(logit)

model(logit logit)

model(logit log)

logit fits

logistic endpoint c.score

and obtains predicted risks using predict, pr.

log fits modified Poisson regression using

glm endpoint c.score, family(poisson) link(log) vce(robust)

and obtains predicted risks using predict, mu. Predicted values below
0 or above 1 are confined to the interval from 0 to 1 before performance
statistics are calculated.

Confidence intervals

noci suppresses the exact confidence intervals around observed risks.
Observed-risk markers and fitted-risk lines remain displayed.

level(#) specifies the confidence level for the exact
Clopper-Pearson binomial confidence intervals. The default is the current
value of set level, usually 95. This option has no visible effect when
noci is specified.

Markers

marker(msymbol) specifies one marker symbol for the observed risks of
all scores. When this option is omitted, scores 1 through 5 use
Oh, Dh, Th, Sh, and oh, respectively.

Fitted-risk lines

plot1opts(line_options) through
plot5opts(line_options) pass line options to the fitted-risk line for
the corresponding score. Examples include lpattern(),
lwidth(), and lcolor().

For example,

plot1opts(lpattern(solid) lwidth(medthick))

plot2opts(lpattern(dash) lwidth(medthick))

Confidence-interval layers

ci1opts(rcap_options) through
ci5opts(rcap_options) pass rcap options to the exact confidence
intervals for the corresponding score. Examples include lpattern(),
lwidth(), and lcolor().

For example,

ci1opts(lwidth(thin))

ci2opts(lpattern(dash) lwidth(thin))

Observed-risk markers

scatter1opts(scatter_options) through
scatter5opts(scatter_options) pass scatter options to the
observed-risk markers for the corresponding score. Examples include
msymbol(), msize(), mcolor(), mfcolor(), and
mlcolor().

For example,

scatter1opts(msymbol(Oh) mlwidth(medthin))

scatter2opts(msymbol(Dh) mlwidth(medthin))

Statistics

nostat suppresses the performance-statistics matrix in the Results
window and suppresses the statistics note on the graph. It does not remove
the statistics stored in r(stats).

statopts(note_options) passes graph-note options to the statistics
note for score 1. Examples include size(), color(),
position(), ring(), and justification().

Only statistics for score 1 are placed in the graph note. Statistics for
all scores remain available in r(stats).

Graph

twoway_options are standard options accepted by twoway. They
may be used to modify the graph title, axis titles, labels, legend, graph
scheme, graph name, and other overall graph properties.

The default legend uses one column and is placed at
position(11) ring(0). A user-specified legend() option may be
used to modify these defaults.

Performance statistics

Expected-to-observed ratio (E:O) is calculated as the sum of predicted
risks divided by the observed number of events. A value of 1 indicates
equality between the expected and observed event counts.

Calibration-in-the-large (CITL) is the intercept from logistic
regression of the endpoint with the logit of predicted risk included as an
offset. The target value is 0.

Calibration slope is the coefficient from logistic regression of the
endpoint on the logit of predicted risk. The target value is 1.

Adjusted R-squared is obtained from weighted linear regression of the
observed risks on the predicted risks across distinct score values. The
number of observations at each score value is used as the analytic weight.
The statistic may be missing when there are too few distinct score values
or when the weighted regression cannot be fitted.

Root mean squared error (RMSE) is calculated across distinct score
values as

RMSE = sqrt[sum n_g(O_g-P_g)^2 / sum n_g],

where n_g is the number of observations, O_g is the observed risk,
and P_g is the predicted risk at score value g.

AUROC is the area under the receiver operating characteristic curve,
calculated from the individual-level predicted risks.

Adjusted R-squared and RMSE are grouped agreement measures. They are not
the scaled Brier score, and the reported RMSE is not the square root of the
individual-level Brier score.

Interpretation

The reported statistics describe apparent performance because the same
analysis sample is used to fit and evaluate each model. They should not be
interpreted as internal validation or external validation.

When a logistic model is fitted and evaluated in the same data,
calibration-in-the-large and calibration slope may be close to their target
values by construction. Resampling or evaluation in independent data is
required to assess optimism and generalizability.

Exact confidence intervals can be wide when few observations are available
at a score value. Their width represents uncertainty in the observed event
proportion and not uncertainty in the fitted-risk line.

Examples

Load the diabetic ketoacidosis demonstration dataset:

download

Install bta2score if it is not available:

ssc install bta2score, replace

Develop the prediction model using logistic regression:

logit dka i.dtx400 i.dm012 insulin low_compli dyspnea infection, cformat(%9.2f) baselevels

Round the coefficients and generate the point-based additive score:

bta2score, tab cstat name(dka_score) replace

Plot the receiver operating characteristic curve:

roctab dka dka_score, graph noref note("AuROC 0.87 (0.82, 0.92)", justification(center) ring(0) position(5) margin(large) size(large)) plotopts(msymbol(none) lwidth(thick) lcolor(black)) yscale(noline) xscale(noline)

Plot the observed and model-predicted risks:

riskcalplot dka dka_score, model(logit) ytitle("Risk of DKA") xtitle("1-DKA score") scheme(stcolor) xlabel(0(3)12)

Stored results

riskcalplot stores the following in r():

Macros

r(models) models corresponding to the score variables

r(scores) names of the score variables

r(endpoint) name of the binary endpoint variable

Matrix

r(stats) performance statistics for all scores

Rows of r(stats) correspond to score variables. Columns are
E_O, CITL, Cal_slope, Adj_R2, RMSE, and
AUROC.

Installation

Install the current version from GitHub:

net install riskcalplot, from("https://raw.githubusercontent.com/suppachai-lawanaskol/riskcalplot/main/") replace

Authors

Suppachai Lawanaskol, MD

Chaiprakarn Hospital

Chiang Mai, Thailand

Jayanton Patumanond, MD, MPH, MSc, DSc

Clinical Epidemiology Unit, Faculty of Medicine

Naresuan University

Phitsanulok, Thailand

Repository:
riskcalplot on GitHub

Suggested citation

Lawanaskol S, Patumanond J. riskcalplot: Stata module for plotting
observed and model-predicted risks across values of discrete clinical
scores. Version 1.0.1, 2026.

Acknowledgments

We gratefully acknowledge Peamyao et al. for providing the dataset and Thanin Lokeskrawee, the corresponding author of our study on the 1-DKA score, for his insightful comments.

References

Clopper CJ, Pearson ES. The use of confidence or fiducial limits illustrated
in the case of the binomial. Biometrika. 1934;26:404-413.

Peamyao W, Lokeskrawee T, Lawanaskol S, Patumanond J, Chanlaor S, Bumrungpagdee W, et al. Predictive factors for diagnosing diabetic ketoacidosis or simple hyperglycemia in adults with high blood glucose: the “1-DKA Alert” study. J Clin Med Res. 2025;17(3):164–173. doi:10.14740/jocmr6180.

Steyerberg EW. Clinical Prediction Models. 2nd ed. Cham:
Springer; 2019.

Zou G. A modified Poisson regression approach to prospective studies with
binary data. American Journal of Epidemiology. 2004;159:702-706.