% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/nl_fit.R
\name{nl_fit}
\alias{nl_fit}
\title{Fit a nonlinear (spline or GAM) single-level or multilevel model}
\usage{
nl_fit(
  data,
  y,
  x,
  time = NULL,
  cluster = NULL,
  nested = FALSE,
  controls = NULL,
  method = c("ns", "bs", "gam"),
  df = 4,
  df_range = 2:8,
  df_criterion = c("AIC", "BIC"),
  k = 5,
  bs_degree = 3,
  random_slope = FALSE,
  family = stats::gaussian(),
  ...
)
}
\arguments{
\item{data}{A data frame (often long format for longitudinal data).}

\item{y}{Outcome variable name (string).}

\item{x}{Focal nonlinear predictor name (string). Must be numeric.}

\item{time}{Optional time variable name (string).}

\item{cluster}{Optional character vector of grouping variable name(s) for
random effects, e.g. \code{NULL}, \code{"id"}, or
\code{c("id", "school")} for two-way clustering.}

\item{nested}{Logical; only used when \code{length(cluster) == 2}. If
\code{TRUE}, uses a nested specification \code{(1 | g1/g2)}; if
\code{FALSE} (default), uses cross-classified
\code{(1 | g1) + (1 | g2)}.}

\item{controls}{Optional character vector of additional covariate names
to include as linear fixed effects.}

\item{method}{Spline basis to use: \code{"ns"} (natural cubic spline,
default), \code{"bs"} (B-spline), or \code{"gam"} (GAM smooth via
\code{mgcv::gam()}). Multilevel fits require \code{"ns"} or \code{"bs"}.}

\item{df}{Degrees of freedom for the spline basis. Supply a single integer
greater than or equal to 1, or the string \code{"auto"} to trigger
automatic selection by information criterion. Default \code{4}.}

\item{df_range}{Integer vector of candidate df values evaluated when
\code{df = "auto"}. Default \code{2:8}.}

\item{df_criterion}{Information criterion used for automatic df selection:
\code{"AIC"} (default) or \code{"BIC"}.}

\item{k}{Basis dimension for \code{mgcv::s()} when \code{method = "gam"}.
Default \code{5}.}

\item{bs_degree}{Polynomial degree for \code{splines::bs()} when
\code{method = "bs"}. Default \code{3} (cubic).}

\item{random_slope}{Logical; if \code{TRUE} and \code{cluster} is supplied,
fits random spline slopes in addition to random intercepts. Currently
implemented only for single-level clustering. Default \code{FALSE}.}

\item{family}{A family object such as \code{stats::gaussian()} (default)
or \code{stats::binomial()}. For multilevel fits, \code{gaussian()} uses
\code{lme4::lmer()} and all other families use \code{lme4::glmer()}.}

\item{...}{Additional arguments passed to the underlying fitting function
(\code{stats::lm()}, \code{mgcv::gam()}, \code{lme4::lmer()}, or
\code{lme4::glmer()}).}
}
\value{
An object of class \code{"nl_fit"} (a named list). It contains
the fitted \code{model} object, the \code{method}, variable names
(\code{y}, \code{x}, \code{time}, \code{cluster}, \code{controls}),
spline settings (\code{df}, \code{df_selected}, \code{df_search},
\code{k}, \code{bs_degree}), flags (\code{nested},
\code{random_slope}), the \code{family}, the model \code{formula},
the \code{call}, and metadata used for prediction (\code{x_info},
\code{levels_info}, \code{control_defaults}).
}
\description{
Fits a nonlinear regression model for an outcome \code{y} with a focal
predictor \code{x}, modeled using natural cubic splines (\code{"ns"}),
B-splines (\code{"bs"}), or GAM smooths (\code{"gam"}).

Version 2 additions: two-way and nested clustering via the
\code{nested} argument; random spline slopes via \code{random_slope};
B-spline basis via \code{method = "bs"}; automatic df selection via
\code{df = "auto"}.
}
\examples{
\dontrun{
# Single-level natural spline with automatic df selection
fit <- nl_fit(data = mydata, y = "score", x = "age", df = "auto")

# Two-way cross-classified clustering
fit2 <- nl_fit(
  data    = mydata,
  y       = "score",
  x       = "age",
  cluster = c("student_id", "school_id"),
  nested  = FALSE
)

# Nested clustering (students within schools)
fit3 <- nl_fit(
  data    = mydata,
  y       = "score",
  x       = "age",
  cluster = c("student_id", "school_id"),
  nested  = TRUE
)

# Random spline slopes
fit4 <- nl_fit(
  data         = mydata,
  y            = "score",
  x            = "age",
  cluster      = "id",
  random_slope = TRUE
)
}

}
\seealso{
\code{\link{nl_predict}}, \code{\link{nl_derivatives}},
\code{\link{nl_compare}}, \code{\link{nl_r2}}, \code{\link{nl_knots}}
}
