View source: R/plsi.logistic.auto.constraint.R
| plsi.logistic.auto.constraint | R Documentation |
Binary-outcome analog of plsi.lr.auto.constraint(): the same model as
plsi.logistic.auto() (penalized regression spline link via
mgcv::gam, family = binomial(), REML smoothing-parameter
selection), but with the single-index direction searched over a
reparameterization that satisfies the identifiability constraint by
construction instead of normalizing after the fact.
plsi.logistic.auto.constraint(
data,
Y.name,
X.name,
Z.name,
k = 10,
bs = "cr",
initial.random.num = 5,
seed = 2026,
maxit = 100
)
data |
A data set including all needed variables |
Y.name |
Variable name for the binary outcome. Must be coded 0/1, or a 2-level factor (which will be coerced to 0/1 by level order, with a message reporting which level became 0 and which became 1). |
X.name |
Variable name vector for exposures (at least 2). |
Z.name |
Variable name vector for confounders |
k |
Upper bound on basis dimension for the smooth link function. Default 10. |
bs |
Smooth basis type passed to |
initial.random.num |
Number of random initials for the single-index direction search |
seed |
A single integer used to seed the RNG so results (random initials and downstream optim() convergence) are reproducible. Set to NULL to skip seeding and use whatever RNG state is already active in the calling environment. Default is 2026. |
maxit |
Maximum number of Nelder-Mead iterations per starting value
for the |
The single-index coefficient \beta is constrained to \|\beta\| = 1
and \beta_1 > 0 for identifiability. The search is reparameterized in
terms of \sigma = (\sigma_1, \dots, \sigma_{p-1}) via
\beta(\sigma) = \{(1 - \|\sigma\|^2)^{1/2}, \sigma_1, \dots,
\sigma_{p-1}\}^T. Both constraints hold automatically for any
\sigma with \|\sigma\| < 1, so optim() runs unconstrained
over \sigma. Standard errors for \beta are obtained from the
Hessian in \sigma-space via the delta method.
The anchor exposure, the one assigned \beta_1, the coordinate
constrained > 0, is chosen as the candidate exposure with the
largest absolute correlation (point-biserial) with the 0/1 outcome,
so an exposure strongly but negatively associated with the outcome can
still be selected as the anchor. Which exposure was selected is reported in
attr(si.coefficient, "note") and in anchor.note of the
returned list.
The confounder-free single-index model is built exactly as in
plsi.logistic.auto(): the confounder contribution from the full
model is fixed as a known offset() and a second binomial gam
is refit directly against the observed y. See
?plsi.logistic.auto for why the residualization approach used for
continuous outcomes does not carry over to binary outcomes.
Standard errors are computed from a numerical Hessian in a local chart of
the unit sphere anchored on the exposure with the largest |\beta_j|
(not necessarily the \beta_1 > 0 anchor), then mapped to
\beta by the delta method. This keeps the finite-difference steps
away from the \|\sigma\| = 1 boundary when the estimated
\beta_1 is small; the point estimates are unaffected.
With exactly two exposures, \sigma is one-dimensional; the search then
uses optim(method = "Brent") on (-1, 1) instead of Nelder-Mead,
which optim() flags as unreliable in one dimension.
The returned object works with all plotting functions using
type = "logistic".
A list of model estimation and prediction results, structured
analogously to plsi.logistic.auto()'s output, plus:
anchor.note: Which exposure was used as the anchor (\beta_1 > 0)
and why; also attached as attr(si.coefficient, "note").
initial.sigma.table: The starting values actually used by the
\sigma-space search.
optim.convergence: For every starting value, the optim()
convergence code (0 = converged, 1 = maxit reached), the number of
log-likelihood evaluations, and the final log-likelihood.
The remaining elements are as in plsi.logistic.auto():
si.coefficient: Single-index direction estimates and inference.
confounder.coefficient: Confounder log-odds coefficients, plus
odds ratios and their 95% CIs.
si.fun: The estimated single-index link function, on both the
logit scale (fit/se/lwr/upr) and the probability scale
(prob.fit/prob.lwr/prob.upr).
si.fun.model: A confounder-free binomial gam on the single index
alone (confounder contribution held as a fixed offset); predict() from
this needs only single_index_estimated (and confounder_offset = 0).
full.model: The full fitted gam (smooth + confounders).
Yuyan Wang
## Not run:
data(nhanes.new)
data <- nhanes.new
X.name <- c("X1_trans.b.carotene", "X2_retinol", "X3_g.tocopherol", "X4_a.tocopherol",
"X5_PCB99", "X6_PCB156", "X7_PCB206",
"X8_3.3.4.4.5.pncb", "X9_1.2.3.4.7.8.hxcdf", "X10_2.3.4.6.7.8.hxcdf")
Z.name <- c("AGE.c", "SEX.Female", "RACE.NH.Black",
"RACE.MexicanAmerican", "RACE.OtherRace", "RACE.Hispanic" )
# demo binary outcome (illustrative only as nhanes.new has no native binary
# variable), simulated from a true single-index combination of the exposures
set.seed(2026)
beta_true <- c(0.30, -0.20, 0.10, 0.40, -0.30, 0.20, -0.10, 0.25, -0.15, 0.35)
beta_true <- beta_true / sqrt(sum(beta_true^2))
x_std <- scale(data[, X.name])
single_index_true <- as.vector(x_std %*% beta_true)
log_odds <- -0.2 + 0.5 * sin(single_index_true) + 0.05 * data$AGE.c
data$high.triglyceride <- stats::rbinom(nrow(data), size = 1, prob = stats::plogis(log_odds))
model_logistic_con <- plsi.logistic.auto.constraint(data = data,
Y.name = "high.triglyceride", X.name = X.name,
Z.name = Z.name, k = 10, bs = "cr",
initial.random.num = 1, seed = 2026)
model_logistic_con$si.coefficient
si.fun.plot(model_logistic_con$si.fun, type = "logistic")
## End(Not run)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.