compare_xnicher: Compare xnicher fits side-by-side via AIC and BIC

View source: R/ic.R

compare_xnicherR Documentation

Compare xnicher fits side-by-side via AIC and BIC

Description

Builds a one-row-per-model summary table for a list of "xnicher" fits, including log-likelihood, parameter count, AIC, BIC, deltas relative to the best model, and Akaike weights.

Usage

compare_xnicher(
  ...,
  sort_by = c("AIC", "BIC", "loglik"),
  comparison_basis = c("unpenalised", "penalised")
)

Arguments

...

Two or more "xnicher" objects, optionally named, OR a single named list of such objects.

sort_by

Character. One of "AIC" (default), "BIC", or "loglik": which metric to order rows by. Best model is always at the top.

comparison_basis

Character, one of "unpenalised" (default) or "penalised". Determines which log-likelihood is used as the basis for AIC and BIC.

  • "unpenalised": the bare data log-likelihood \ell(\hat\theta) returned by logLik.xnicher. Standard frequentist convention, and the right basis when comparing **different likelihood families** at fixed penalty knobs.

  • "penalised": the optimiser's actual objective, \ell(\hat\theta) - \mathrm{pen}(\hat\theta), i.e. x$best$loglik. The right basis when comparing **the same family at different penalty strengths**, since the unpenalised log-likelihood is monotone in (\lambda_{\mu}, \lambda_{\log\sigma}, \lambda_{\alpha}) and would always favour \lambda = 0. Note: this score is NOT a true frequentist IC – it is the penalised-objective AIC, an effective-fit score.

Details

All fits MUST have been produced from the same env_occ; any mismatch in nobs or in the variable-name ordering raises an error, since IC values are not comparable across heterogeneous data.

Value

A data.frame with one row per fit and columns:

model

Name (or call index) of the fit.

likelihood

Likelihood family (x$likelihood).

loglik

Un-penalised log-likelihood at convergence.

df

Number of free parameters.

nobs

Sample size (occurrences).

AIC, BIC

Information criteria.

dAIC, dBIC

Deltas vs. the minimum.

weight_AIC

Akaike weights, \exp(-\Delta_i / 2) / \sum_j \exp(-\Delta_j / 2).

convergence

ucminfcpp convergence code.

Caveats

AIC and BIC compare *likelihoods* on the SAME observed data. When comparing weighted vs. presence-only families, both families evaluate \log L on n_{occ} occurrences; the weighted family additionally normalises by an env_m integral, so its likelihood is on a different scale. In this implementation, logLik(weighted) returns the full weighted-likelihood value (occurrence sum minus log-denominator), which is the right thing for **within-family** comparison (e.g., weighted vs. skew_normal_weighted) but should be interpreted with care when contrasting weighted with presence-only.

Examples


fit_w   <- optimize_niche(example_env_occ_2d, example_env_m_2d,
                          num_starts = 5L, likelihood = "weighted")
fit_skn <- optimize_niche(example_env_occ_2d, example_env_m_2d,
                          num_starts = 5L, likelihood = "skew_normal_weighted")
compare_xnicher(weighted = fit_w, skew_normal = fit_skn)


xnicher documentation built on Sept. 15, 2026, 5:08 p.m.