Compute the continuous monotonicity and convexity indices, inflection
and turning-point counts, and rule-based shape category for a fitted
univariate smooth. Works on either a per-pair fit object returned
from the janusplot internal machinery or a freshly fitted
mgcv::gam() with a single s() term.
Both indices are bounded in [-1, 1] and weighted by the empirical
density of the predictor:
monotonicity_index(paper symbolM). Letfbe the fitted smooth evaluated on a dense grid ofn_gridequally-spaced points across the predictor range,f'its numerical first derivative, andwthe empirical density of the predictor on the same grid withsum(w) = 1. Thenmonotonicity_index = sum(w * f') / sum(w * |f'|) in [-1, 1].+1is strictly increasing,-1strictly decreasing,0non-monotone.convexity_index(paper symbolC). Withf''the numerical second derivative on the same grid,convexity_index = sum(w * f'') / sum(w * |f''|) in [-1, 1].+1is globally convex (bowl-up),-1globally concave (bowl-down),0inflection-dominated (S-curve, sine, flat).
Both indices are scale-invariant (replacing y -> a*y + b leaves
them unchanged) and density-weighted so they describe the smooth
where the data actually live, not extrapolated tails.
Usage
janusplot_shape_metrics(
fit,
x_name = NULL,
newdata = NULL,
n_grid = 200L,
cutoffs = janusplot_shape_cutoffs()
)Arguments
- fit
Either a list returned by a janusplot pair-fit helper (must contain
predandraw), or a fittedmgcv::gam()with a singles(x)term.- x_name
Character. Column name of the predictor when
fitis amgcv::gam()object. Ignored for pair-fit lists.- newdata
Optional data frame supplying the raw predictor values used for density weighting when
fitis amgcv::gam()object. IfNULL, the model frame is used.- n_grid
Integer. Prediction grid length when
fitis amgcv::gam()object. Default200L.- cutoffs
Named list of classification thresholds; see
janusplot_shape_cutoffs(). Default uses package defaults.
Value
A named list with components:
monotonicity_indexMin[-1, 1]. See Description.convexity_indexCin[-1, 1]. See Description.n_turning_pointsInteger count of lobe-mass-weighted sign changes of
f'. Equals the number of interior extrema.n_inflectionsInteger count of lobe-mass-weighted sign changes of
f''.flat_range_ratiorange(f) / sd(y)— small values indicate a degenerate flat smooth.shape_categoryOne of 24 labels from
janusplot_shape_hierarchy()dispatched on(n_turning_points, n_inflections)with(monotonicity_index, convexity_index)disambiguation for the monotone case.
See also
janusplot_shape_cutoffs(), janusplot(), janusplot_data().
Other shape-metrics:
janusplot_shape_cutoffs(),
janusplot_shape_hierarchy()
Examples
# On a fitted gam
set.seed(2026L)
n <- 200L
x <- stats::runif(n, 0, 10)
y <- log1p(x) + stats::rnorm(n, sd = 0.3)
d <- data.frame(x = x, y = y)
fit <- mgcv::gam(y ~ s(x), data = d, method = "REML")
janusplot_shape_metrics(fit, x_name = "x", newdata = d)
#> $monotonicity_index
#> [1] 1
#>
#> $convexity_index
#> [1] -0.9342494
#>
#> $n_turning_points
#> [1] 0
#>
#> $n_inflections
#> [1] 0
#>
#> $flat_range_ratio
#> [1] 3.161499
#>
#> $shape_category
#> [1] "concave_up"
#>
