| Version: | 1.0 |
| Title: | Create, Edit, and Plot Nomograms using R6 Objects |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| Maintainer: | Greg Snow <538280@gmail.com> |
| Description: | Nomograms are a type of plot for displaying linear models. A scale is plotted for each predictor in the model that translates values of the variable into "points", the sum of the "points" is then looked up on another scale to find the final prediction from the model. This package provides an R6 object constructor that does the computations for you to create an object representing the nomogram for the model. Methods and fields in the object allow you to customize the nomogram. You can then plot the nomogram, further customize, replot, etc. These types of nomograms are described in Harrell (2015) <doi:10.1007/978-3-319-19425-7>. |
| URL: | https://github.com/glsnow/R6Nomogram |
| Imports: | R6 |
| Suggests: | quarto |
| Encoding: | UTF-8 |
| Config/roxygen2/version: | 8.0.0 |
| VignetteBuilder: | quarto |
| NeedsCompilation: | no |
| Packaged: | 2026-06-30 19:03:53 UTC; gls33 |
| Author: | Greg Snow [aut, cre] |
| Repository: | CRAN |
| Date/Publication: | 2026-07-06 13:50:17 UTC |
Nomogram R6 Object
Description
R6Nomogram builds and plots a nomogram from a fitted regression
model (e.g. lm, glm, coxph, ...). Given the model and
the data used to fit it, the object computes, for each predictor (or
interaction term) in the model, an axis that maps predictor values to a
common "points" scale. The points scale is in turn related back to the
model's linear predictor and to the fitted response, so that the
nomogram can be read by summing points across predictors and converting
the total back to a predicted response.
Details
The construction of a nomogram proceeds through a small pipeline of
steps, all of which are run automatically by initialize() by default
(and can
also be re-run individually if axes need to be adjusted):
-
neworinitialize- initialize object and store model, terms, and newdat in the object. -
PopulateVars()- extract variable names, term-level predictions, and response predictions from the model and data. -
create.x()- build sorted, de-duplicated predictor values and the corresponding points for each axis. -
shift()- shift each axis so that point values start at a convenient origin (by default, 0). -
scale()- rescale all axes so that the maximum number of points is a convenient round number (by default, 100). -
pretty()/pretty.y()- choose "pretty" tick locations for the predictor axes and for the total points / linear predictor / response axis.
Once built, plot() draws the nomogram, and tables() returns
the same information as a list of data frames (e.g. for use outside of a
plot).
Public fields
modelThe fitted model object (e.g. from
lm,glm,coxph, etc.) used to construct the nomogram.termsThe
termsobject describing the model formula (generated by thepredictmethod withtype='terms').newdataThe data frame used to build the nomogram, either supplied by the user or extracted from
model.var.namesCharacter vector of the variable names appearing in the model formula (excluding the response).
x.namesCharacter vector of names for each predictor/interaction axis on the nomogram (interaction terms are joined with
":").x.labelsCharacter vector of axis labels used when plotting (defaults to
x.names).orig.xData frame of the original predictor variable values extracted from
newdata.orig.termsData frame of the model's term-level (partial) predictions, one column per term.
orig.responseVector of unique predicted response values (response scale).
x.valsList, one element per axis, of the unique, sorted predictor (or interaction) values.
x.pointsList, one element per axis, of the points corresponding to
x.vals.x.pretty.valsList of "pretty" axis tick values used for plotting.
x.pretty.pointsList of point positions corresponding to
x.pretty.vals.x.y.offsetsList controlling the vertical offset/justification of axis labels when plotting.
scale.cNumeric scaling constant relating points back to the linear predictor scale.
constantThe model intercept/offset constant, adjusted as points are shifted and scaled.
total.pointsNumeric vector of total points corresponding to the unique fitted values.
linear.predictorNumeric vector of linear predictor values corresponding to
total.points.pretty.total.pointsNumeric vector of "pretty" total-point tick values for the response axis.
pretty.linear.predictorNumeric vector of linear predictor values matching
pretty.total.points.pretty.responseNumeric vector of response values matching
pretty.total.points.plot.lpLogical; whether to plot a separate linear-predictor axis in addition to total points and response.
v.pos.xNumeric vector of vertical plotting positions for the predictor axes.
v.pos.rNumeric vector of vertical plotting positions for the total points / linear predictor / response axes.
optionsList of plotting options:
tik.len,txt.pos,points.nint,signif.digits,text.par,line.par, andtick.par. The last 3 default to empty lists, but can be lists with any of the parameters that can be passed totextorsegments. They can also be a list of lists with the element names matchingself$x.namesto give different options for each scale.points.labLabel for the "Points" axis.
total.points.labLabel for the "Total Points" axis.
lp.labLabel for the "Linear Predictor" axis.
resp.labLabel for the "Response" axis.
tp.rangeNumeric vector giving the range of total points used to position the response axis.
verboseLogical; whether to print progress messages.
parlist of parameter settings in place during the last plot. This can be used with the
parfunction if you are manually adding to the plot.
Methods
Public methods
R6Nomogram$new()
Construct a new R6Nomogram. Runs the full construction
pipeline (loading data, populating variables, creating axes,
shifting, scaling, and prettying) up to the requested steps.
Usage
R6Nomogram$new( model, newdata, verbose = TRUE, steps = Inf, type.terms = "terms", type.response = "response" )
Arguments
modelA fitted model object (e.g. from
lm,glm, orcoxph).newdataOptional data frame to use instead of the data stored in/with
model. If missing, the data is recovered frommodel$data, thedataargument ofmodel$call, ormodel.frame(model), in that order.verboseLogical; print progress messages for each step.
stepsNumeric; how many construction steps to run (useful for stopping partway through, e.g. to inspect or adjust axes by hand before continuing). Defaults to
Inf, i.e. run all steps.type.termsThe
typeargument passed topredict()to obtain term-level predictions.type.responseThe
typeargument passed topredict()to obtain response-scale predictions.
Returns
The object itself, invisibly.
R6Nomogram$PopulateVars()
Extract variable names, term-level predictions, and response
predictions from model and newdata, and use them to
populate x.names, x.labels, orig.x,
orig.terms, orig.response, constant,
total.points, and linear.predictor.
Usage
R6Nomogram$PopulateVars( model = self$model, newdata = self$newdata, type.terms = "terms", type.response = "response" )
Arguments
modelA fitted model object. Defaults to
self$model.newdataA data frame of predictor values. Defaults to
self$newdata.type.termsThe
typeargument passed topredict()to obtain term-level predictions.type.responseThe
typeargument passed topredict()to obtain response-scale predictions.
Returns
The object itself, invisibly.
R6Nomogram$create.x()
Build, for each axis (predictor or interaction term), the unique,
sorted predictor values (x.vals) and their corresponding
points (x.points), derived from orig.x and
orig.terms.
Usage
R6Nomogram$create.x()
Returns
The object itself, invisibly.
R6Nomogram$shift()
Shift the points for one or more axes by a constant offset. By
default, each axis named in w is shifted so that its minimum
point value becomes 0; total.points and constant are
updated to match so that the overall model is unaffected.
Usage
R6Nomogram$shift(w = self$x.names, v, update.constant = TRUE)
Arguments
wCharacter vector of axis names (from
x.names) to shift. Defaults to all axes.vNumeric vector of shift amounts, one per element of
w(matched by name if named). If missing, each axis is shifted so that the minimum number of points is 0.update.constantLogical; if
TRUE(the default),total.pointsandconstantare updated so totals remain consistent with the shifted axes.
Returns
The object itself, invisibly.
R6Nomogram$scale()
Rescale all axes (and total.points) so that the largest point
value across all axes equals max.points. scale.c is
updated so that points can still be converted back to the linear
predictor scale.
Usage
R6Nomogram$scale(max.points = 100)
Arguments
max.pointsThe desired maximum number of points. Defaults to 100.
Returns
The object itself, invisibly.
R6Nomogram$pretty()
Choose "pretty" tick locations for one or more predictor axes, by
interpolating (via a natural spline of points on values) the points
corresponding to each chosen tick value. Results are stored in
x.pretty.vals and x.pretty.points. Factor axes are
left as-is (every level is used as a "pretty" value).
Usage
R6Nomogram$pretty(w = self$x.names, v)
Arguments
wCharacter vector of axis names (from
x.names) to process. Defaults to all axes.vControls the chosen tick values for each axis in
w. If missing, ticks are chosen automatically viaaxisTicks(). If a single number, it is used as thenintargument toaxisTicks(). If a list, each element gives the tick values for the corresponding axis (matched by name). If a numeric vector, it is used directly as the tick values for every axis inw.
Returns
The object itself, invisibly.
R6Nomogram$pretty.y()
Choose "pretty" tick locations for the total points / linear
predictor / response axis, by interpolating (via a natural spline of
response on total points) the response corresponding to each chosen
tick value. Results are stored in pretty.total.points,
pretty.linear.predictor, and pretty.response.
Usage
R6Nomogram$pretty.y(v)
Arguments
vControls the chosen total-points tick values. If missing, ticks are chosen automatically via
axisTicks(). If a single number, it is used as thenintargument toaxisTicks(). Otherwise, used directly as the tick values.
Returns
The object itself, invisibly.
R6Nomogram$plot()
Plot the nomogram. Draws the predictor axes (plot.x) and/or
the total points / linear predictor / response axes (plot.y)
using base graphics, with appearance controlled by self$options
(text.par, line.par, tick.par, etc.). If
predict is supplied, a prediction line is drawn connecting the
predicted points on each predictor axis to the corresponding total on
the response axis.
Usage
R6Nomogram$plot(plot.x = TRUE, plot.y = TRUE, predict, ...)
Arguments
plot.xLogical; draw the predictor axes. Default
TRUE.plot.yLogical; draw the total points / linear predictor / response axes. Default
TRUE.predictOptional named list or data frame of predictor values for which to draw a prediction line/segments on the nomogram.
...Additional graphical parameters, passed to
par().
Returns
The object itself, invisibly.
R6Nomogram$grconvertX()
Convert a value from one nomogram axis scale to the points scale.
For from = "Total Points", converts a total-points value to
its plotting position on the points axis. For any other axis name,
converts a predictor value (numeric or factor level) to its points
value via spline interpolation (numeric axes) or direct lookup
(factor axes).
Usage
R6Nomogram$grconvertX(x, from = "Total Points", verbose)
Arguments
xValue(s) to convert.
fromCharacter; the axis to convert from. Either
"Total Points"(the default) or one ofx.names.verboseLogical; print progress messages. Defaults to
self$verbose.
Returns
The converted value(s), or NA (with a warning) if
from does not match "Total Points" or any axis name.
R6Nomogram$tables()
Summarize the nomogram as a list of data frames: one data frame per
predictor axis (giving x.pretty.vals and
x.pretty.points), plus a final Response data frame
giving pretty.total.points, pretty.linear.predictor,
and pretty.response.
Usage
R6Nomogram$tables()
Returns
A named list of data frames.
R6Nomogram$clone()
The objects of this class are cloneable with this method.
Usage
R6Nomogram$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Author(s)
Greg Snow <538280@gmail.com>
References
Regression Modeling Strategies, Frank Harrell <doi:10.1007/978-3-319-19425-7>
See Also
The nomogram function in the rms package
Examples
mtcars2 <- mtcars
mtcars2$cyl <- factor(mtcars2$cyl)
mtcars2$gear <- factor(mtcars2$gear)
mtcars2$vs <- factor(mtcars2$vs)
fit <- glm(mpg ~ poly(wt,2) + poly(disp,2) + cyl*gear + vs,
data=mtcars2, family=gaussian(link=inverse))
n1 <- R6Nomogram$new(fit)
n1$plot()
n1$options$tik.len <- 0.4
n1$options$txt.pos <- 1.2
n1$options$signif.digits <- 3
n1$x.pretty.vals$`cyl:gear` <-
c("Other", "", "", "", "6:4", "", "6:5", "8:5")
n1$pretty.y(seq(60, 200, by=10))
n1$pretty('wt', c(1.5, 2, 3, 3.5, 4, 4.25, 4.5,
4.75, 5, 5.25, 5.4))
n1$pretty('disp', c(75, 100, 125, 150, 175, 200, 250,
300, 400, 450))
n1$plot.lp <- TRUE
n1$v.pos.r <- NULL # it will be recreated properly in next plot
n1$lp.lab <- "G/M"
n1$resp.lab <- "M/G"
n1$options$text.par[['linear predictor']] <- list(cex=0.8)
n1$plot()
rm(mtcars2)