
Inspect profile confidence-interval shape for a fitted model
Source:R/confint-inspect.R
confint_inspect.RdUse confint_inspect() when a profile confidence interval is
missing, one-sided, very wide, or hard to trust. Most users should
start with confint.gllvmTMB_multi() or the matching extract_*()
interval helper; this function is the advanced visual check for a
direct profile target.
Usage
confint_inspect(
fit,
parm,
level = 0.95,
ystep = 0.5,
ytol = NULL,
parm.range = c(-Inf, Inf)
)Arguments
- fit
A fit returned by
gllvmTMB().- parm
Character. A single profile-target label from
profile_targets(). Examples:"sigma_eps","sd_B[1]","phi_nbinom2[2]","b_fix[1]". Derived targets are not accepted by this direct-parameter diagnostic.- level
Confidence level. Default
0.95.- ystep
Profile grid spacing on the deviance scale, passed to
TMB::tmbprofile(). Default0.5.- ytol
Profile maximum-deviance budget, passed to
TMB::tmbprofile(). DefaultNULL, which sizes the budget for the requestedlevel(the crossing threshold plus a margin). A budget below the threshold cannot produce a crossing, so the bound would come back infinite; supply a number only if you want to override that.- parm.range
Two-element numeric range (in the TMB-link scale) for the profile walk, passed to
TMB::tmbprofile(). Defaultc(-Inf, Inf).
Value
An object of class gllvmTMB_confint_inspect with
components:
$curveData frame with one row per profile-grid point. Columns:
parm(user-facing label),parm_value_natural(parameter value on the natural scale after the registered transformation),parm_value_link(parameter value on the TMB optimisation scale),nll(negative log-likelihood),deviance_drop(2 * (nll - mle_nll), the chi-squared statistic),excess_over_threshold(deviance_drop - chi2_threshold; negative is inside CI, positive is outside),in_ci(logical).$boundsData frame, 1 row:
parm,estimate_natural,lower_natural,upper_natural,wald_lower_natural,wald_upper_natural,wald_profile_disagree_lower,wald_profile_disagree_upper. Wald bounds come fromfit$sd_report$cov.fixedvia the delta method; disagreement flags are TRUE when the absolute difference exceeds 25% of the Wald half-width (a heuristic for "look at the plot").$plotA
ggplotobject visualising the curve, MLE, chi-squared threshold, profile bounds (vertical lines), and Wald bounds (dashed vertical lines for comparison).NULLifggplot2is not installed.$diagnosticsNamed character vector flagging any of:
"no_heuristic_warning"(none of this helper's shape warnings fired; this does not prove a quadratic profile),"asymmetric"(skewed, Wald-vs-profile disagrees),"flat_at_mle","hits_lower_bound","hits_upper_bound","no_lower_crossing","no_upper_crossing","profile_failed".$callThe
match.call()of the invocation.
Details
It returns the full profile-likelihood curve, the deviance bounds,
and (when ggplot2 is available) a ggplot visualisation showing
the curve, the MLE, the chi-squared threshold, and the resulting
confidence-interval bounds. It surfaces a small set of numerical shape
warnings before the user interprets the bound; the returned label is not a
goodness or calibration certificate.
This helper inspects direct profile-ready targets from
profile_targets(). Nonlinear derived targets such as communality,
repeatability, and trait
correlation do not currently have a public profile-inspection route. A
working direct curve does not establish empirical interval coverage for
every model class.
Common patterns to look for in the returned plot (see the profile-likelihood article):
Quadratic and approximately symmetric near the MLE: Wald and profile may agree closely for this target.
Asymmetric or skewed: inspect the endpoint status and constrained-fit stability before preferring either interval.
Flat near the MLE: the target may be weakly informed, or the numerical profile may need closer inspection.
Hits a parameter-range bound: interpret the endpoint on the target's transformed scale and distinguish a natural boundary from a truncated search.
No usable crossing: treat the endpoint as unavailable; do not replace it automatically with bootstrap output unless simulation, refits, failed replicate counts, and Monte Carlo resolution are credible for that target.
See also
confint.gllvmTMB_multi() (the corresponding CI
extractor; same parm vocabulary), profile_targets() (the
target inventory), tmbprofile_wrapper() (the lower-level profile API),
and the
profile-likelihood article.
Examples
set.seed(1)
# Four traits measured twice on each of 80 units (e.g. individuals),
# sharing one latent axis.
sim <- simulate_unit_trait(n_units = 80, n_obs_per_unit = 2,
n_traits = 4,
Lambda_B = matrix(c(0.9, 0.8, -0.7, 0.5)),
psi_B = 0.3, sigma2_eps = 0.3)
fit <- gllvmTMB(value ~ 0 + trait +
latent(0 + trait | unit, d = 1, unique = TRUE),
data = sim$data, trait = "trait", unit = "unit")
# Profile the residual standard deviation (true value sqrt(0.3) = 0.55).
# The profile tracks how much worse the fit gets as sigma_eps moves
# away from its estimate; the interval is the range where that loss
# stays below the chi-squared threshold.
insp <- confint_inspect(fit, parm = "sigma_eps")
# Printing shows the profile and Wald bounds side by side, followed by
# any shape warnings.
insp
#>
#> ── gllvmTMB confint_inspect for "sigma_eps" ────────────────────────────────────
#>
#> ── Estimate + CI ──
#>
#> parm estimate_natural lower_natural upper_natural
#> log_sigma_eps sigma_eps 0.582798 0.5404067 0.6310422
#> wald_lower_natural wald_upper_natural wald_profile_disagree_lower
#> log_sigma_eps 0.5393509 0.629745 FALSE
#> wald_profile_disagree_upper
#> log_sigma_eps FALSE
#> ── Diagnostics ──
#>
#> ℹ No heuristic shape warning fired. Inspect the curve directly; this does not prove quadratic shape or calibrated coverage.
#> The $plot component is a <ggplot>; call `plot(result$plot)` to render.
# A few points of the profile curve.
head(insp$curve[, c("parm_value_natural", "deviance_drop", "in_ci")])
#> parm_value_natural deviance_drop in_ci
#> 1 0.5295040 6.281139 FALSE
#> 2 0.5329037 5.446743 FALSE
#> 3 0.5363252 4.675053 FALSE
#> 4 0.5397687 3.965273 FALSE
#> 5 0.5467221 2.728302 TRUE
#> 6 0.5537651 1.729648 TRUE
# Plot the curve with the threshold, the estimate and both intervals
# (needs the ggplot2 package).
if (requireNamespace("ggplot2", quietly = TRUE)) {
plot(insp$plot)
}