| Title: | Parametric Modal Regression with Right Censoring |
|---|---|
| Description: | Implements parametric modal regression for continuous positive distributions of the exponential family and beyond (e.g., Log-Logistic, Birnbaum-Saunders) under right censoring. Provides functions to link the conditional mode to a linear predictor using alternative parameterizations. Includes maximum likelihood estimation via numerical optimization, asymptotic inference based on the observed Fisher information matrix, and model diagnostics using randomized quantile residuals. See Galarza and Lachos (2026) <doi:10.48550/arXiv.2603.07099>. |
| Authors: | Christian Galarza [aut, cre], Victor Lachos [aut] |
| Maintainer: | Christian Galarza <[email protected]> |
| License: | GPL-3 |
| Version: | 0.2.0 |
| Built: | 2026-05-14 09:13:21 UTC |
| Source: | https://github.com/chedgala/modalcens |
Fits a parametric modal regression model under right censoring by linking
the conditional mode to a linear predictor via a family-specific
link function .
The density of each family is reparameterized so that appears
explicitly, obtained by solving
.
The resulting mode-parameter mappings are:
| Family | Link | Mode mapping |
| Gamma | log | ,\ |
| Beta | logit | ,\ |
| Weibull | log | ,\ |
| Inv. Gauss | log | ,\ |
| Log-Normal | log | ,\ |
| Log-Logistic | log | ,\ |
| Birnbaum-Saunders | log | ,\
|
The censored log-likelihood is
where for right-censored observations and
is the survival function.
Maximization is performed via the BFGS algorithm with analytical Hessian
for asymptotic standard errors.
modal_cens(formula, data, cens, family = "gamma")modal_cens(formula, data, cens, family = "gamma")
formula |
An object of class "formula" (e.g., y ~ x1 + x2). |
data |
A data frame containing the variables in the model. Must not
contain missing values ( |
cens |
A binary numeric vector indicating censoring status:
|
family |
A character string naming the distribution family: |
An object of class "ModalCens" containing:
Estimated regression coefficients (beta vector).
Estimated dispersion/shape parameter (on original scale).
Full covariance matrix (p+1 x p+1), including log_phi.
Covariance matrix for regression coefficients only (p x p).
Estimated conditional modes.
Randomized quantile residuals (Dunn-Smyth).
Maximized log-likelihood value.
Number of observations used in fitting.
Total number of estimated parameters.
Distribution family used.
Censoring indicator vector as supplied.
The matched call.
The model terms object.
Response variable.
Objects of class "ModalCens" support the following S3 methods:
summary()Coefficient table with standard errors, z-values, and p-values; dispersion parameter; log-likelihood; AIC; BIC; and pseudo R-squared.
plot()Two-panel diagnostic plot: (1) residuals vs.\ fitted modes, distinguishing observed and censored points; (2) normal Q-Q plot of randomized quantile residuals.
coef()Estimated regression coefficients .
vcov()Full covariance matrix
including log_phi. Use object$vcov_beta for the
submatrix of regression coefficients only.
residuals()Randomized quantile residuals (Dunn & Smyth,
1996), which follow under the correct model,
even under censoring.
logLik()Maximized log-likelihood value.
AIC() / BIC()
Information criteria computed as
with or .
Christian Galarza and Victor Lachos
Yao, W., & Li, L. (2014). A new regression model: modal linear regression. Scandinavian Journal of Statistics, 41(3), 656-671.
Galarza, C. E., & Lachos, V. H. (2026). Parametric Modal Regression for Positive Distributions. arXiv preprint, arXiv:2603.07099. <doi:10.48550/arXiv.2603.07099>
Dunn, P. K., & Smyth, G. K. (1996). Randomized quantile residuals. Journal of Computational and Graphical Statistics, 5(3), 236-244.
data(trees, package = "datasets") set.seed(007) # Simulate 15% right-censoring (for didactic purposes) q85 <- quantile(trees$Volume, 0.85) cens_ind <- as.integer(trees$Volume > q85) # 1 = censored, 0 = observed # (0,1) rescaling for Beta ys <- (trees$Volume - min(trees$Volume) + 1) / (max(trees$Volume) - min(trees$Volume) + 2) q85b <- quantile(ys, 0.85) cens_b <- as.integer(ys > q85b) # Build datasets df_orig <- data.frame(y = pmin(trees$Volume, q85), cens = cens_ind, Girth = trees$Girth, Height = trees$Height) df_beta <- data.frame(y = pmin(ys, q85b), cens = cens_b, Girth = trees$Girth, Height = trees$Height) # Fit all families datasets <- list(gamma = df_orig, weibull = df_orig, invgauss = df_orig, lognormal = df_orig, beta = df_beta, loglogistic = df_orig, bisa = df_orig) models <- list(); aic_values <- list() for (f in names(datasets)) { mod <- try(modal_cens(y ~ Girth + Height, data = datasets[[f]], cens = datasets[[f]]$cens, family = f), silent = TRUE) if (!inherits(mod, "try-error")) { models[[f]] <- mod; aic_values[[f]] <- AIC(mod) } } # Select best model by AIC and analyse best <- names(which.min(aic_values)) cat("Best family:", best, "| AIC =", round(aic_values[[best]], 3), "\n") fit <- models[[best]] summary(fit) plot(fit) confint(fit)data(trees, package = "datasets") set.seed(007) # Simulate 15% right-censoring (for didactic purposes) q85 <- quantile(trees$Volume, 0.85) cens_ind <- as.integer(trees$Volume > q85) # 1 = censored, 0 = observed # (0,1) rescaling for Beta ys <- (trees$Volume - min(trees$Volume) + 1) / (max(trees$Volume) - min(trees$Volume) + 2) q85b <- quantile(ys, 0.85) cens_b <- as.integer(ys > q85b) # Build datasets df_orig <- data.frame(y = pmin(trees$Volume, q85), cens = cens_ind, Girth = trees$Girth, Height = trees$Height) df_beta <- data.frame(y = pmin(ys, q85b), cens = cens_b, Girth = trees$Girth, Height = trees$Height) # Fit all families datasets <- list(gamma = df_orig, weibull = df_orig, invgauss = df_orig, lognormal = df_orig, beta = df_beta, loglogistic = df_orig, bisa = df_orig) models <- list(); aic_values <- list() for (f in names(datasets)) { mod <- try(modal_cens(y ~ Girth + Height, data = datasets[[f]], cens = datasets[[f]]$cens, family = f), silent = TRUE) if (!inherits(mod, "try-error")) { models[[f]] <- mod; aic_values[[f]] <- AIC(mod) } } # Select best model by AIC and analyse best <- names(which.min(aic_values)) cat("Best family:", best, "| AIC =", round(aic_values[[best]], 3), "\n") fit <- models[[best]] summary(fit) plot(fit) confint(fit)