% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/shape-metrics.R
\name{janusplot_shape_metrics}
\alias{janusplot_shape_metrics}
\title{Shape metrics for a fitted univariate smooth}
\usage{
janusplot_shape_metrics(
  fit,
  x_name = NULL,
  newdata = NULL,
  n_grid = 200L,
  cutoffs = janusplot_shape_cutoffs()
)
}
\arguments{
\item{fit}{Either a list returned by a janusplot pair-fit helper
(must contain \code{pred} and \code{raw}), or a fitted \code{\link[mgcv:gam]{mgcv::gam()}} with
a single \code{s(x)} term.}

\item{x_name}{Character. Column name of the predictor when \code{fit} is
a \code{\link[mgcv:gam]{mgcv::gam()}} object. Ignored for pair-fit lists.}

\item{newdata}{Optional data frame supplying the raw predictor values
used for density weighting when \code{fit} is a \code{\link[mgcv:gam]{mgcv::gam()}} object.
If \code{NULL}, the model frame is used.}

\item{n_grid}{Integer. Prediction grid length when \code{fit} is a
\code{\link[mgcv:gam]{mgcv::gam()}} object. Default \code{200L}.}

\item{cutoffs}{Named list of classification thresholds; see
\code{\link[=janusplot_shape_cutoffs]{janusplot_shape_cutoffs()}}. Default uses package defaults.}
}
\value{
A named list with components:
\describe{
\item{\code{monotonicity_index}}{\code{M} in \verb{[-1, 1]}. See Description.}
\item{\code{convexity_index}}{\code{C} in \verb{[-1, 1]}. See Description.}
\item{\code{n_turning_points}}{Integer count of lobe-mass-weighted
sign changes of \verb{f'}. Equals the number of interior extrema.}
\item{\code{n_inflections}}{Integer count of lobe-mass-weighted
sign changes of \verb{f''}.}
\item{\code{flat_range_ratio}}{\code{range(f) / sd(y)} — small values
indicate a degenerate flat smooth.}
\item{\code{shape_category}}{One of 24 labels from
\code{\link[=janusplot_shape_hierarchy]{janusplot_shape_hierarchy()}} dispatched on
\verb{(n_turning_points, n_inflections)} with
\verb{(monotonicity_index, convexity_index)} disambiguation for
the monotone case.}
}
}
\description{
\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}}

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
\code{\link[mgcv:gam]{mgcv::gam()}} with a single \code{s()} term.

Both indices are bounded in \verb{[-1, 1]} and weighted by the empirical
density of the predictor:
\itemize{
\item \code{monotonicity_index} (paper symbol \code{M}). Let \code{f} be the fitted
smooth evaluated on a dense grid of \code{n_grid} equally-spaced
points across the predictor range, \verb{f'} its numerical first
derivative, and \code{w} the empirical density of the predictor on
the same grid with \code{sum(w) = 1}. Then
\verb{monotonicity_index = sum(w * f') / sum(w * |f'|) in [-1, 1]}.
\code{+1} is strictly increasing, \code{-1} strictly decreasing, \code{0}
non-monotone.
\item \code{convexity_index} (paper symbol \code{C}). With \verb{f''} the numerical
second derivative on the same grid,
\verb{convexity_index = sum(w * f'') / sum(w * |f''|) in [-1, 1]}.
\code{+1} is globally convex (bowl-up), \code{-1} globally concave
(bowl-down), \code{0} inflection-dominated (S-curve, sine, flat).
}

Both indices are scale-invariant (replacing \code{y -> a*y + b} leaves
them unchanged) and density-weighted so they describe the smooth
\emph{where the data actually live}, not extrapolated tails.
}
\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)
}
\seealso{
\code{\link[=janusplot_shape_cutoffs]{janusplot_shape_cutoffs()}}, \code{\link[=janusplot]{janusplot()}}, \code{\link[=janusplot_data]{janusplot_data()}}.

Other shape-metrics: 
\code{\link{janusplot_shape_cutoffs}()},
\code{\link{janusplot_shape_hierarchy}()}
}
\concept{shape-metrics}
