| Title: | Beta Regression for Interval-Censored Scale-Derived Outcomes |
|---|---|
| Description: | Maximum-likelihood estimation of beta regression models for responses derived from bounded rating scales. Observations are treated as interval-censored on (0, 1) after a scale-to-unit transformation, and the likelihood is built from the difference of the beta CDF at the interval endpoints. The complete likelihood supports mixed censoring types: uncensored, left-censored, right-censored, and interval-censored observations. Both fixed- and variable-dispersion submodels are supported, with flexible link functions for the mean and precision components. A compiled C++ backend (via 'Rcpp' and 'RcppArmadillo') provides numerically stable, high-performance log-likelihood evaluation. Standard S3 methods (print(), summary(), coef(), fitted(), residuals(), predict(), plot(), confint(), vcov(), logLik(), AIC(), BIC()) are available for fitted objects. |
| Authors: | José Evandeilton Lopes [aut, cre] (ORCID: <https://orcid.org/0009-0007-5887-4084>), Wagner Hugo Bonat [aut] (ORCID: <https://orcid.org/0000-0002-0349-7054>) |
| Maintainer: | José Evandeilton Lopes <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 3.0.0 |
| Built: | 2026-09-30 00:43:33 UTC |
| Source: | https://github.com/evandeilton/betaregscale |
Akaike information criterion
## S3 method for class 'brs' AIC(object, ..., k = 2)## S3 method for class 'brs' AIC(object, ..., k = 2)
object |
A fitted |
... |
Ignored. |
k |
Penalty per parameter (default 2). |
Scalar AIC value.
brs, logLik.brs, BIC.brs,
brs_gof
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) AIC(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) AIC(fit)
AIC for brsmm models
## S3 method for class 'brsmm' AIC(object, ..., k = 2)## S3 method for class 'brsmm' AIC(object, ..., k = 2)
object |
A fitted |
... |
Currently ignored. |
k |
Numeric penalty per parameter. |
Numeric scalar.
brsmm, logLik.brsmm,
BIC.brsmm, brs_gof
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) AIC(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) AIC(fit)
Compares fitted "brs" and "brsmm" models by log-likelihood,
AIC, BIC and likelihood-ratio tests (Lopes, 2023, "Inferencia").
## S3 method for class 'brs' anova(object, ..., test = c("Chisq", "none"))## S3 method for class 'brs' anova(object, ..., test = c("Chisq", "none"))
object |
A fitted |
... |
Further fitted |
test |
|
The models are sorted by their number of parameters. For consecutive
models the statistic is , with Chi Df
the difference in the number of parameters, and
. The models must be nested; this is not
checked. They must also describe the same response: the same observations,
interval, ncuts and (under "mid") lim, or the
call stops, since different coarsenings are different likelihoods.
When the larger model adds one random-effect term (a "brs" model
against a random-intercept "brsmm", or one more correlated random
term), its variance lies on the boundary of the parameter space under
and follows the mixture
(Self and Liang, 1987;
Stram and Lee, 1994); for one variance component alone this is
, i.e. half the naive p-value. The
printed heading names the rows that use it. When more than one random term
is added at once, the naive p-value is kept and flagged
as conservative.
An object of class "anova" (a data frame) with columns
Df, logLik, AIC, BIC and, for
test = "Chisq", Chisq, Chi Df and
Pr(>Chisq); the attribute "heading" explains the p-values.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Self, S. G., and Liang, K.-Y. (1987). Asymptotic properties of maximum likelihood estimators and likelihood ratio tests under nonstandard conditions. Journal of the American Statistical Association, 82(398), 605–610. doi:10.1080/01621459.1987.10478472
Stram, D. O., and Lee, J. W. (1994). Variance components testing in the longitudinal mixed effects model. Biometrics, 50(4), 1171–1177. doi:10.2307/2533455
anova.brsmm, summary.brs,
logLik.brs
# Synthetic NRS-11 scores: 4 groups x 3 times. Simulated, not real data. set.seed(2023) nrs <- expand.grid(id = 1:80, time = c("6h", "12h", "24h")) nrs$group <- factor(paste0("g", (nrs$id - 1) %% 4 + 1)) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + c(0, -0.1, 0.05, 0.1)[nrs$group] shp <- brs_repar(mu = plogis(eta), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # Time only (m1) nested in time + group (m2): LR test on 3 df m1 <- brs(y ~ time, data = nrs, ncuts = 10) m2 <- brs(y ~ time + group, data = nrs, ncuts = 10) anova(m1, m2) # Fits under different interval directions are different response models m2_right <- brs(y ~ time + group, data = nrs, ncuts = 10, interval = "right") try(anova(m2, m2_right))# Synthetic NRS-11 scores: 4 groups x 3 times. Simulated, not real data. set.seed(2023) nrs <- expand.grid(id = 1:80, time = c("6h", "12h", "24h")) nrs$group <- factor(paste0("g", (nrs$id - 1) %% 4 + 1)) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + c(0, -0.1, 0.05, 0.1)[nrs$group] shp <- brs_repar(mu = plogis(eta), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # Time only (m1) nested in time + group (m2): LR test on 3 df m1 <- brs(y ~ time, data = nrs, ncuts = 10) m2 <- brs(y ~ time + group, data = nrs, ncuts = 10) anova(m1, m2) # Fits under different interval directions are different response models m2_right <- brs(y ~ time + group, data = nrs, ncuts = 10, interval = "right") try(anova(m2, m2_right))
anova() for "brsmm" fits: the same table as
anova.brs, with the chi-bar-square mixture
for rows that add one
random-effect term, whose variance is on the boundary under .
This is the test to use for a variance component: the Wald statistic of
its log standard deviation is not meaningful (see
summary.brsmm).
## S3 method for class 'brsmm' anova(object, ..., test = c("Chisq", "none"))## S3 method for class 'brsmm' anova(object, ..., test = c("Chisq", "none"))
object |
A fitted |
... |
Further fitted |
test |
|
An object of class "anova"; see anova.brs.
Self, S. G., and Liang, K.-Y. (1987). Asymptotic properties of maximum likelihood estimators and likelihood ratio tests under nonstandard conditions. Journal of the American Statistical Association, 82(398), 605–610. doi:10.1080/01621459.1987.10478472
anova.brs, brsmm,
summary.brsmm
set.seed(11) g <- 20 d <- data.frame(id = factor(rep(1:g, each = 8)), x = runif(8 * g)) shp <- brs_repar(plogis(-0.4 + d$x + rnorm(g, sd = 0.6)[d$id]), phi = 0.25) d$y <- round(10 * rbeta(nrow(d), shp$shape1, shp$shape2)) m0 <- brs(y ~ x, data = d, ncuts = 10) m1 <- brsmm(y ~ x, random = ~ 1 | id, data = d, ncuts = 10) anova(m0, m1) # Pr(>Chisq) = half the chi2(1) tailset.seed(11) g <- 20 d <- data.frame(id = factor(rep(1:g, each = 8)), x = runif(8 * g)) shp <- brs_repar(plogis(-0.4 + d$x + rnorm(g, sd = 0.6)[d$id]), phi = 0.25) d$y <- round(10 * rbeta(nrow(d), shp$shape1, shp$shape2)) m0 <- brs(y ~ x, data = d, ncuts = 10) m1 <- brsmm(y ~ x, random = ~ 1 | id, data = d, ncuts = 10) anova(m0, m1) # Pr(>Chisq) = half the chi2(1) tail
Produces ggplot2 diagnostics tailored to interval-censored scale models.
## S3 method for class 'brs' autoplot( object, type = c("calibration", "score_dist", "cdf", "residuals_by_delta", "all"), bins = 10L, scores = NULL, newdata = NULL, n_grid = 200L, max_curves = 6L, residual_type = "rqr", title = NULL, xlab = NULL, ylab = NULL, ncol = 2L, theme = ggplot2::theme_minimal(), ... )## S3 method for class 'brs' autoplot( object, type = c("calibration", "score_dist", "cdf", "residuals_by_delta", "all"), bins = 10L, scores = NULL, newdata = NULL, n_grid = 200L, max_curves = 6L, residual_type = "rqr", title = NULL, xlab = NULL, ylab = NULL, ncol = 2L, theme = ggplot2::theme_minimal(), ... )
object |
A fitted |
type |
Plot type: |
bins |
Number of bins for |
scores |
Optional integer vector of scores for |
newdata |
Optional data frame of covariate scenarios for |
n_grid |
Number of points on |
max_curves |
Maximum number of CDF curves shown when |
residual_type |
Residual type for |
title |
Optional character: override the plot title via
|
xlab |
Optional character: override the x-axis label.
Ignored when |
ylab |
Optional character: override the y-axis label.
Ignored when |
ncol |
Number of columns for the grid when |
theme |
A ggplot2 theme object (e.g., |
... |
Additional arguments forwarded to |
type = "calibration" bins predictions and compares mean observed vs
mean predicted response in each bin.
type = "score_dist" compares observed score frequencies against
expected frequencies implied by the fitted beta interval model.
A ggplot2 object.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
brs, plot.brs,
autoplot.brs_bootstrap
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), x2 = rep(c(0, 0, 1, 1), 5) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1 + x2, data = prep) ggplot2::autoplot(fit, type = "calibration") ggplot2::autoplot(fit, type = "calibration", title = "My calibration", ylab = "Observed" ) ggplot2::autoplot(fit, type = "all")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), x2 = rep(c(0, 0, 1, 1), 5) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1 + x2, data = prep) ggplot2::autoplot(fit, type = "calibration") ggplot2::autoplot(fit, type = "calibration", title = "My calibration", ylab = "Observed" ) ggplot2::autoplot(fit, type = "all")
Produces visual summaries for objects returned by brs_bootstrap.
## S3 method for class 'brs_bootstrap' autoplot( object, type = c("ci_forest", "dist", "qq", "stability"), parameter = NULL, title = NULL, caption = NULL, max_parameters = 12L, ci_level = NULL, theme = NULL, ... )## S3 method for class 'brs_bootstrap' autoplot( object, type = c("ci_forest", "dist", "qq", "stability"), parameter = NULL, title = NULL, caption = NULL, max_parameters = 12L, ci_level = NULL, theme = NULL, ... )
object |
An object of class |
type |
Plot type:
|
parameter |
Optional parameter name used by |
title |
Optional plot title override. |
caption |
Optional subtitles/titles for plot types. Accepts:
|
max_parameters |
Maximum number of parameters shown in
|
ci_level |
Confidence level used in |
theme |
Optional ggplot2 theme object (e.g., |
... |
Currently ignored. |
For type = "dist", "qq", and "stability",
bootstrap draws must be present in attr(object, "boot_draws"),
obtained by fitting with brs_bootstrap(..., keep_draws = TRUE).
A ggplot2 object.
brs_bootstrap, brs,
autoplot.brs
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) boot <- brs_bootstrap(fit, R = 50) ggplot2::autoplot(boot, type = "ci_forest")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) boot <- brs_bootstrap(fit, R = 50) ggplot2::autoplot(boot, type = "ci_forest")
Produces visual summaries for objects returned by
brs_marginaleffects.
## S3 method for class 'brs_marginaleffects' autoplot( object, type = c("forest", "magnitude", "dist"), variable = NULL, top_n = 12L, title = NULL, caption = NULL, theme = NULL, ... )## S3 method for class 'brs_marginaleffects' autoplot( object, type = c("forest", "magnitude", "dist"), variable = NULL, top_n = 12L, title = NULL, caption = NULL, theme = NULL, ... )
object |
An object of class |
type |
Plot type: |
variable |
Optional variable name for |
top_n |
Maximum number of variables shown in |
title |
Optional plot title override. |
caption |
Optional subtitle override. |
theme |
Optional ggplot2 theme object. If |
... |
Currently ignored. |
type = "dist" requires AME simulation draws stored in
attr(object, "ame_draws"), which are available when marginal
effects are computed with keep_draws = TRUE and interval = TRUE.
A ggplot2 object.
brs_marginaleffects, brs,
autoplot.brs
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) ame <- brs_marginaleffects(fit) ggplot2::autoplot(ame, type = "forest")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) ame <- brs_marginaleffects(fit) ggplot2::autoplot(ame, type = "forest")
Produces ggplot2 diagnostics tailored to mixed beta interval models.
## S3 method for class 'brsmm' autoplot( object, type = c("calibration", "score_dist", "ranef_qq", "residuals_by_group", "ranef_caterpillar", "ranef_density", "ranef_pairs", "shrinkage", "all"), bins = 10L, scores = NULL, residual_type = c("response", "pearson"), max_groups = 25L, title = NULL, xlab = NULL, ylab = NULL, ncol = 2L, theme = ggplot2::theme_minimal(), ... )## S3 method for class 'brsmm' autoplot( object, type = c("calibration", "score_dist", "ranef_qq", "residuals_by_group", "ranef_caterpillar", "ranef_density", "ranef_pairs", "shrinkage", "all"), bins = 10L, scores = NULL, residual_type = c("response", "pearson"), max_groups = 25L, title = NULL, xlab = NULL, ylab = NULL, ncol = 2L, theme = ggplot2::theme_minimal(), ... )
object |
A fitted |
type |
Plot type. One of |
bins |
Number of bins for |
scores |
Optional integer vector of scores for |
residual_type |
Residual type for |
max_groups |
Maximum groups in |
title |
Optional character: override the plot title via
|
xlab |
Optional character: override the x-axis label.
Ignored when |
ylab |
Optional character: override the y-axis label.
Ignored when |
ncol |
Number of columns for the grid when |
theme |
A ggplot2 theme object (e.g., |
... |
Additional arguments forwarded to |
A ggplot2 object, or (when type = "all") invisibly
returns the list of all panels after rendering the grid.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit_mm <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) ggplot2::autoplot(fit_mm, type = "calibration", bins = 4) ggplot2::autoplot(fit_mm, type = "ranef_caterpillar", title = "My title", ylab = "Mode" ) ggplot2::autoplot(fit_mm, type = "all")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit_mm <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) ggplot2::autoplot(fit_mm, type = "calibration", bins = 4) ggplot2::autoplot(fit_mm, type = "ranef_caterpillar", title = "My title", ylab = "Mode" ) ggplot2::autoplot(fit_mm, type = "all")
Bayesian information criterion
## S3 method for class 'brs' BIC(object, ...)## S3 method for class 'brs' BIC(object, ...)
object |
A fitted |
... |
Ignored. |
Scalar BIC value.
brs, logLik.brs, AIC.brs,
brs_gof
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) BIC(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) BIC(fit)
with = the number of observations
(nobs(object)), as lme4 does, and the number of
parameters (fixed effects, precision and packed random-effect
parameters). There is no single sample size for a mixed model: counting
groups instead ( object$ngroups) penalises more and is a
common alternative, -2 * logLik(object) + log(object$ngroups) * k.
Compare BIC values only between fits with the same convention.
## S3 method for class 'brsmm' BIC(object, ...)## S3 method for class 'brsmm' BIC(object, ...)
object |
A fitted |
... |
Currently ignored. |
Numeric scalar.
brsmm, logLik.brsmm,
AIC.brsmm, brs_gof
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) BIC(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) BIC(fit)
Fits by maximum likelihood a beta regression for scores on a bounded scale,
treated as coarsened (interval-censored) observations of a latent beta
variable (Lopes, 2023). A one-part formula y ~ x1 + x2 keeps the
second parameter constant (brs_fit_fixed); a two-part formula
y ~ x1 + x2 | z1 + z2 also models it (brs_fit_var).
brs( formula, data, link = NULL, link_phi = NULL, ncuts = NULL, lim = NULL, repar = 2L, method = c("BFGS", "L-BFGS-B"), hessian_method = c("cpp", "numDeriv", "optim"), interval = NULL, start = NULL, control = list() )brs( formula, data, link = NULL, link_phi = NULL, ncuts = NULL, lim = NULL, repar = 2L, method = c("BFGS", "L-BFGS-B"), hessian_method = c("cpp", "numDeriv", "optim"), interval = NULL, start = NULL, control = list() )
formula |
A |
data |
Data frame. |
link |
Link for the first parameter (the mean under
|
link_phi |
Link for the second parameter. |
ncuts |
Integer |
lim |
Half-width of the score cell in |
repar |
Reparameterization scheme (default 2); see
|
method |
Optimization method (default |
hessian_method |
How the Hessian for |
interval |
Direction of the uncertainty interval, |
start |
Optional numeric vector of starting values (mean
coefficients, then dispersion coefficients). |
control |
Control list for |
The scores run over with ncuts: the
scale has categories and is its maximum. A scale that
starts at 1, such as a Likert item 1–5, must be shifted to 0–4 and
fitted with ncuts = 4; otherwise the lowest category is read as an
interior score and the censoring of the lower border is lost.
Raw scores are converted to cells and censoring types by
brs_check with ncuts, lim and interval;
data from brs_prep or brs_sim are used as they
are, with their stored ncuts, lim and interval. Values
in are exact observations. The model is
with obtained from by
brs_repar.
An object of class "brs": a list with, among others,
par (estimates on the link scales), coefficients
(mean and precision parts), value (maximised
log-likelihood), hessian, convergence, diagnostics
(see 'Fit diagnostics'), hatmu (first parameter per observation:
the mean, or the shape under repar = 0), hatphi,
Y (columns left, right, yt, y,
delta), ncuts, lim, interval, repar,
link and link_phi.
With cell and censoring type ,
where and are the beta density and distribution function
with shapes . The four factors are exact values
(), the lowest score (, left-censored),
the highest score (, right-censored) and the other scores
(, interval-censored). This is eq.
eqn_verossimilhanca_geral of Lopes (2023); the table of censoring
types in the same section swaps the labels and
, and the package follows the equation.
Numerical details: endpoints are clamped to
and there is no probability floor; an
interval probability uses lower-tail probabilities when the interval
midpoint is at or below the mean and upper tails
otherwise, which avoids cancellation; below an endpoint
Laplace approximation of the tail replaces it; a non-finite
contribution becomes , as does a NaN parameter. The mean and the dispersion
(repar = 2) are clamped to , the
precision and the shape to , and the beta
shapes to .
optim (method = "BFGS", the default, or
"L-BFGS-B"; maxit = 5000 unless control says
otherwise) maximises the log-likelihood, which is evaluated in C++. The
gradient uses the chain rule on the two linear predictors: the derivatives
of each contribution with respect to and
are Richardson central differences with step
, and the gradient is
and . The Hessian behind
vcov() is built the same way from the per-observation second
derivatives (step ;
hessian_method = "cpp", the default):
with diagonal matrices of the second derivatives of each
contribution in . "numDeriv"
differentiates the log-likelihood with numDeriv::hessian() and
"optim" takes the finite-difference Hessian of optim.
Lopes (2023, "Estimacao") also uses BFGS with numerical derivatives; here
they are taken on the linear predictors, not on the coefficients.
Starting values: start when given (bootstrap and jackknife refits
pass the parent estimate); otherwise a quasi-binomial GLM of the cell
midpoints for the mean, and for the second parameter the moment estimate on
the midpoints as the intercept with zero slopes; under repar = 0
both shapes by the method of moments. The covariance matrix is
at the estimate (vcov.brs); no generalised
inverse is used.
Before optim, the mean and precision model matrices are checked
(pivoted QR, tolerance ; condition number of the matrix with
unit-length columns). After it, fit$diagnostics holds
grad_norm (largest absolute gradient), grad_gain (the
log-likelihood a Newton step would still gain,
), grad_step (that
step in standard errors), min_eig,
max_eig and min_eig_scaled (eigenvalues of , the last
in correlation form), hessian_nd, n_clamped and
clamped (observations on the clamps of the likelihood). Each problem
gives one line:
Some columns are linear combinations of others (the message names them). Remove or recode them.
Condition number above
: estimates and standard errors are unstable. Drop or combine
the named columns, or centre them.
optim stopped at its
iteration limit or failed. Try method = "L-BFGS-B", rescale the
covariates or simplify the model.
A Newton step would
still gain more than 0.01 in log-likelihood although optim
reported convergence. Refit with the other method; the message
asks to rescale the covariates when their scales differ by more than
(e.g. a raw income next to a dummy).
The likelihood is nearly flat or curved the wrong way in
some direction: a parameter that is not identified, or covariates on
very different scales (the message then asks to rescale them).
vcov() returns NA for variances it cannot estimate; use
likelihood-ratio tests (anova.brs) or
brs_bootstrap instead of Wald statements, rescale, or
simplify the model.
Fitted means, dispersions or shapes sit on the numerical limits above, typically because a group of observations lies entirely at one end of the scale (separation) or every observation is censored on the same side. The coefficients drift towards infinity and are not interpretable; merge sparse groups or remove the separating covariate.
brsmm adds a check of the variance components.
repar |
parameters (Lopes, 2023) | link |
link_phi |
| 0 | shapes ; eq. eqn_beta_p1 (regression on the
shapes is a package extension) |
log, sqrt |
log, sqrt |
| 1 | mean , precision ;
"parametrizacao 1" (Ferrari and Cribari-Neto, 2004) |
logit, probit, cauchit, cloglog |
log, sqrt |
| 2 | mean , dispersion ;
"parametrizacao 2" (Bayer, 2011), written there
|
logit, probit, cauchit, cloglog |
logit, probit, cauchit, cloglog
|
The first link of each cell is the default (link = NULL,
link_phi = NULL); any other combination is an error.
"identity", "inverse" and "1/mu^2" are not accepted
for positive parameters. With "sqrt" the inverse link is flat for
, and a warning is issued when a fitted linear predictor
lies there. The mean and variance of under each scheme are given
in brs_repar. Under repar = 0 the object stores the
shape in hatmu, while fitted(),
predict(type = "response"), residuals and marginal effects use
.
interval = "mid" (default) uses the cells
; "right" and
"left" use equal cells (the
dissertation's and , with a package normalisation).
"right" and "left" give the same fit and differ only in
predict(type = "score"); "mid" and "right"/"left"
are different coarsening models, whose log-likelihoods and AIC are not
comparable. Details: brs_check.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
Bayer, F. M. (2011). Modelagem e inferencia em regressao beta. PhD thesis, Universidade Federal de Pernambuco.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
brs_check, brs_prep,
brs_repar, summary.brs,
predict.brs, residuals.brs,
brs_predict_scoreprob, anova.brs,
brsmm
# Synthetic NRS-11 pain scores (0-10, so ncuts = 10): 4 groups x 3 # post-operative times, patterned on the knee-surgery design of Lopes (2023). # Simulated, not real data. set.seed(2023) nrs <- expand.grid(id = 1:80, time = c("6h", "12h", "24h")) nrs$group <- factor(paste0("g", (nrs$id - 1) %% 4 + 1)) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + c(0, -0.1, 0.05, 0.1)[nrs$group] shp <- brs_repar(mu = plogis(eta), phi = 0.3, repar = 2) # dispersion 0.3 nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # Default cells [s - 0.5, s + 0.5] / 10; scores 0 and 10 are censored fit <- brs(y ~ time + group, data = nrs, ncuts = 10) summary(fit) confint(fit) # Post-fit checks: no log-likelihood left to gain, negative definite Hessian, no clamps fit$diagnostics[c("grad_gain", "hessian_nd", "n_clamped")] # Same scores read with right-direction cells [s, s + 1] / 11 fit_r <- brs(y ~ time + group, data = nrs, ncuts = 10, interval = "right") cbind(mid = coef(fit), right = coef(fit_r)) # New patients: mean on (0, 1), latent score, expected score, P(S = s) nd <- data.frame(time = c("6h", "12h", "24h"), group = "g1") predict(fit, newdata = nd) predict(fit, newdata = nd, type = "score") predict(fit, newdata = nd, type = "expected_score") round(brs_predict_scoreprob(fit, newdata = nd), 3) # Randomized quantile residuals respect the censoring (N(0, 1) under the model) set.seed(1) summary(residuals(fit, type = "rqr")) plot(fit, which = 1:2)# Synthetic NRS-11 pain scores (0-10, so ncuts = 10): 4 groups x 3 # post-operative times, patterned on the knee-surgery design of Lopes (2023). # Simulated, not real data. set.seed(2023) nrs <- expand.grid(id = 1:80, time = c("6h", "12h", "24h")) nrs$group <- factor(paste0("g", (nrs$id - 1) %% 4 + 1)) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + c(0, -0.1, 0.05, 0.1)[nrs$group] shp <- brs_repar(mu = plogis(eta), phi = 0.3, repar = 2) # dispersion 0.3 nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # Default cells [s - 0.5, s + 0.5] / 10; scores 0 and 10 are censored fit <- brs(y ~ time + group, data = nrs, ncuts = 10) summary(fit) confint(fit) # Post-fit checks: no log-likelihood left to gain, negative definite Hessian, no clamps fit$diagnostics[c("grad_gain", "hessian_nd", "n_clamped")] # Same scores read with right-direction cells [s, s + 1] / 11 fit_r <- brs(y ~ time + group, data = nrs, ncuts = 10, interval = "right") cbind(mid = coef(fit), right = coef(fit_r)) # New patients: mean on (0, 1), latent score, expected score, P(S = s) nd <- data.frame(time = c("6h", "12h", "24h"), group = "g1") predict(fit, newdata = nd) predict(fit, newdata = nd, type = "score") predict(fit, newdata = nd, type = "expected_score") round(brs_predict_scoreprob(fit, newdata = nd), 3) # Randomized quantile residuals respect the censoring (N(0, 1) under the model) set.seed(1) summary(residuals(fit, type = "rqr")) plot(fit, which = 1:2)
Computes bootstrap-based confidence intervals for the parameters of a
fitted "brs" model by repeatedly simulating data from the fitted
model and re-estimating parameters. Only "brs" (fixed or
variable-dispersion) objects are supported; "brsmm" is not supported.
brs_bootstrap( object, R = 199L, level = 0.95, ci_type = c("percentile", "basic", "normal", "bca"), max_tries = NULL, keep_draws = FALSE ) ## S3 method for class 'brs_bootstrap' print(x, ...)brs_bootstrap( object, R = 199L, level = 0.95, ci_type = c("percentile", "basic", "normal", "bca"), max_tries = NULL, keep_draws = FALSE ) ## S3 method for class 'brs_bootstrap' print(x, ...)
object |
A fitted |
R |
Integer: number of bootstrap replicates (default 199). |
level |
Numeric: confidence level (default 0.95). |
ci_type |
Character: type of confidence interval. One of
|
max_tries |
Optional integer: maximum number of bootstrap attempts
to obtain converged replicates. If |
keep_draws |
Logical: if |
x |
Object returned by |
... |
Ignored. |
Each replicate draws a new response
at the fitted shapes of the rows used by the fit and substitutes it into a
copy of object$data; covariates, factor levels, transformations and
the formula stay those of the original fit, which is then re-fitted with
brs under the same ncuts, lim, interval,
links, repar and optimizer. The observation mechanism of each row is
reproduced: exact observations () stay continuous; scores
are re-coarsened on the fit's grid (the mapping of brs_sim).
Rows whose bounds came from the analyst (brs_prep Modes 2–4,
bounds that are not the cell of the row's score) keep their thresholds as
fixed and non-informative (independent of ), and is
re-drawn by the cell of the partition they induce where falls:
for an upper bound , gives on
, otherwise on
(an interval gives three cells). When the original design had
more thresholds than a row records (e.g. Mode 4 intervals cut from a finer
instrument) the bootstrap is conservative, and for Mode 2 rows with a
forced (a threshold built from the score itself, which is
informative) it is only an approximation. The response must be a variable
(not an expression such as I(y / 10)).
Each refit starts from the estimate of object and uses the compiled
Hessian (hessian_method = "cpp"), so replicates are cheap.
Replicates that fail (refit error, non-convergence, non-finite estimates)
are discarded and counted: attributes "n_failed" and
"fail_rate", also printed. Intervals are computed from the bootstrap
distribution of each parameter, with the method controlled by
ci_type: "percentile" (default) uses the raw empirical
quantiles; "basic" uses reflected empirical quantiles;
"normal" uses a normal approximation from the bootstrap standard
error (no quantiles); "bca" uses bias-corrected-and-accelerated
adjusted quantiles. With parametric resampling and a nonparametric
(leave-one-out) jackknife acceleration, "bca" is an approximation;
a warning says so once per session, and failed jackknife refits are
reported in "n_jack_failed".
A data frame with columns parameter, estimate
(original point estimate), se_boot (bootstrap standard error),
ci_lower, ci_upper, mcse_lower, mcse_upper,
wald_lower, wald_upper, and level. The attribute
"n_success" gives the number of replicates that converged.
Additional attributes include "R", "n_attempted",
"n_failed", "fail_rate", "n_jack_failed" (BCa
only), "ci_type", and optionally "boot_draws".
print(brs_bootstrap): Print method for bootstrap results
ci_type = "bca"
The bias-corrected and accelerated interval needs an acceleration constant,
which is obtained here by a leave-one-out jackknife. That requires n
additional model fits, one per observation, on top of the R bootstrap
replicates: the total is R + n fits rather than R. The cost is
therefore driven by the sample size, not by R, and grows quickly –
for n = 1000 the jackknife alone dominates the run time by an order of
magnitude. The other three interval types need only the R replicates.
Prefer "percentile" or "basic" for exploratory work on large
samples, and reserve "bca" for a final result.
confint.brs for Wald intervals;
brs_sim for simulation; brs for fitting.
# Synthetic NRS-11 scores at 6h, 12h, 24h (time is a factor) set.seed(3) nrs <- data.frame(time = factor(rep(c("6h", "12h", "24h"), each = 40), levels = c("6h", "12h", "24h"))) shp <- brs_repar(mu = plogis(-1.3 + c(0, 0.75, 0.3)[nrs$time]), phi = 0.3) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) fit <- brs(y ~ time, data = nrs, ncuts = 10) # Percentile intervals from 30 parametric replicates (use R >= 199 in practice) set.seed(4) bt <- brs_bootstrap(fit, R = 30) bt # Bootstrap next to Wald limits, and the bootstrap/Wald SE ratio cols <- c("parameter", "ci_lower", "ci_upper", "wald_lower", "wald_upper") as.data.frame(bt)[, cols] round(bt$se_boot / sqrt(diag(vcov(fit))), 2)# Synthetic NRS-11 scores at 6h, 12h, 24h (time is a factor) set.seed(3) nrs <- data.frame(time = factor(rep(c("6h", "12h", "24h"), each = 40), levels = c("6h", "12h", "24h"))) shp <- brs_repar(mu = plogis(-1.3 + c(0, 0.75, 0.3)[nrs$time]), phi = 0.3) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) fit <- brs(y ~ time, data = nrs, ncuts = 10) # Percentile intervals from 30 parametric replicates (use R >= 199 in practice) set.seed(4) bt <- brs_bootstrap(fit, R = 30) bt # Bootstrap next to Wald limits, and the bootstrap/Wald SE ratio cols <- c("parameter", "ci_lower", "ci_upper", "wald_lower", "wald_upper") as.data.frame(bt)[, cols] round(bt$se_boot / sqrt(diag(vcov(fit))), 2)
Produces a visual summary of the censoring structure in a fitted
"brs" model or a response matrix produced by
brs_check. The summary includes:
Bar chart of censoring-type counts, with percentage labels (censoring burden).
Boxplot (with jittered points) of the midpoint response
by censoring type.
Boxplot of interval width () by censoring type.
Ordered interval map: segments for a sample
of observations, colored by censoring type.
brs_cens( object, n_sample = 100L, which = 1:4, caption = NULL, gg = FALSE, title = "Censoring diagnostic overview", sub.caption = NULL, theme = NULL, palette = NULL, inform = FALSE, ... )brs_cens( object, n_sample = 100L, which = 1:4, caption = NULL, gg = FALSE, title = "Censoring diagnostic overview", sub.caption = NULL, theme = NULL, palette = NULL, inform = FALSE, ... )
object |
A fitted |
n_sample |
Integer: maximum number of observations to show in the interval plot (default 100). If the data has more observations, a random sample is drawn. |
which |
Integer vector selecting which panels to draw
(default |
caption |
Optional panel captions. Accepts a character vector (or list coercible to character) with up to 4 labels, in the order: burden, midpoint-by-type, width-by-type, ordered interval map. |
gg |
Logical: use ggplot2? (default |
title |
Optional global title for the plotting page. |
sub.caption |
Optional subtitle/caption for the plotting page. |
theme |
Optional ggplot2 theme object (e.g., |
palette |
Optional named character vector with colors for censoring
types |
inform |
Logical; if |
... |
Further arguments (currently ignored). |
Invisibly returns a data frame with censoring counts and proportions, percentages, and interpretation flags.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
y <- c(0, 3, 5, 7, 10) Y <- brs_check(y, ncuts = 10) brs_cens(Y) prep <- brs_prep(data.frame(y = y), ncuts = 10) brs_cens(prep)y <- c(0, 3, 5, 7, 10) Y <- brs_check(y, ncuts = 10) brs_cens(Y) prep <- brs_prep(data.frame(y = y), ncuts = 10) brs_cens(prep)
Maps a score on ( ncuts, the
maximum score; categories) to a cell of
and to a censoring type of the complete
likelihood (Lopes, 2023, eq. eqn_verossimilhanca_geral; see
brs): density ,
, ,
. A value in is exact
(), observation by observation. A scale that starts at 1
(e.g. a Likert item 1–5) must be shifted to start at 0 (0–4,
ncuts = 4): its lowest category is then the left-censored border.
brs_check( y, ncuts = 100L, lim = 0.5, delta = NULL, interval = c("mid", "right", "left") )brs_check( y, ncuts = 100L, lim = 0.5, delta = NULL, interval = c("mid", "right", "left") )
y |
Numeric vector: scores on |
ncuts |
Integer |
lim |
Numeric in |
delta |
Integer vector or |
interval |
Direction of the uncertainty interval: |
With delta = NULL, each value in is exact and each
other value is a score with its cell and the type above; this is the rule
of brs_prep too. Input that mixes values in
with values is ambiguous (proportions next to scores, or
rescaled scores) and gives one warning; rescale it if the values in
are meant as scores (half-point scores 0, 0.5, 1, ...: use
y * 2 and ncuts * 2). A user-supplied delta (the
mechanism brs_sim uses in Monte Carlo studies) forces the
type per observation and keeps the cell endpoints of the score:
|
|
|
| 0 | cell centre (or when in ) |
same |
| 1 | |
|
| 2 | |
|
| 3 | |
|
A forced or 2 uses the cell of the observed score as the
censoring threshold, so the threshold depends on : applied to every
observation this is informative censoring and the likelihood has no finite
maximum (brs_sim warns).
Under "mid" with lim = 0.5: ,
and .
Scores outside are an error (as in brs_prep),
and so is a observation with
(zero-probability interval). When the clamp squeezes a cell to zero width
(a cell narrower than at a border, i.e. ncuts too
large or lim too small), the error says so.
yt is the cell centre: under "mid" (so the border
scores sit at and ) and
otherwise; exact values are kept. It is the
density argument for and the point used by the midpoint
residuals; censored contributions do not use it.
Data carrying the "is_prepared" attribute (from
brs_prep or brs_sim) are used by
brs as they are; brs_check() runs only for raw scores.
A numeric matrix with one row per observation and columns
left (), right (), yt (cell
centre), y (the input) and delta.
interval is the direction of the uncertainty interval around the
score (Lopes, 2023, "Mapeamento de intervalos para beta":
, , ).
interval |
cell of score |
latent score of
|
"mid" |
|
|
"right" |
|
|
"left" |
|
|
The latent score is the back-transformation used by
predict(type = "score"): it lies in ,
or when is in the cell of
. The cells of "right" and "left" are
equal and partition . This is a package choice that differs
from the dissertation, which divides and by ; there
the two directions differ by and chapter 4 reports opposite
intercept biases for them, while here they give the same likelihood and
the same coefficients. The three directions are different coarsening
models of the same scores: their log-likelihoods are not comparable, and
anova.brs refuses such comparisons. lim applies to
"mid" only.
Lopes (2023, "Mudanca de escala intervalar") rescales scores by the range
and handles the edge effect either with the transformation
(Smithson and Verkuilen, 2006), which
depends on the sample size and the observed range , or by
moving 0 and 1 inwards by . The package does neither:
each score is coarsened into its cell, using the scale maximum
rather than the observed range; the border scores 0 and become
left- and right-censored observations with contributions and
; and the endpoints are clamped to
, , only as a
numerical guard. The border cells therefore keep their full probability,
no data are moved towards 1/2, and the fit does not depend on .
The clamp does not enter the border contributions ( ignores
, ignores ); it matters only for exact
values and for extreme user-supplied intervals.
The censoring type is derived from the score, before any clamping:
, , otherwise
.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Smithson, M., and Verkuilen, J. (2006). A better lemon squeezer? Maximum-likelihood regression with beta-distributed dependent variables. Psychological Methods, 11(1), 54–71. doi:10.1037/1082-989X.11.1.54
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
brs_prep for analyst-supplied censoring and
intervals; brs; brs_sim.
# NRS-11 scores (K = 10) under the three interval directions s <- 0:10 brs_check(s, ncuts = 10) # mid: [s - 0.5, s + 0.5] / 10 brs_check(s, ncuts = 10, interval = "right") # right: [s, s + 1] / 11 # "left" has the same cells as "right"; only the latent score read back differs identical(brs_check(s, 10, interval = "left"), brs_check(s, 10, interval = "right")) # Borders: score 0 -> delta 1 (F(u)), score 10 -> delta 2 (1 - F(l)) brs_check(c(0, 10), ncuts = 10)[, c("left", "right", "delta")] # A Likert item 1-5: shift to 0-4 so that K = ncuts = 4 is its maximum likert <- c(1, 2, 3, 5, 4) brs_check(likert - 1, ncuts = 4)[, c("left", "right", "delta")] # Unshifted, category 1 would be an interior cell and 0 a category never used brs_check(likert, ncuts = 5)[, "delta"] # Values already in (0, 1) are exact observations (delta 0) brs_check(c(0.12, 0.5, 0.97)) # Per observation: 0.3 is exact, 5 and 10 are scores (with a warning) brs_check(c(0.3, 5, 10), ncuts = 10) # A forced delta keeps the cell of the score brs_check(c(30, 60), ncuts = 100, delta = c(1L, 2L))# NRS-11 scores (K = 10) under the three interval directions s <- 0:10 brs_check(s, ncuts = 10) # mid: [s - 0.5, s + 0.5] / 10 brs_check(s, ncuts = 10, interval = "right") # right: [s, s + 1] / 11 # "left" has the same cells as "right"; only the latent score read back differs identical(brs_check(s, 10, interval = "left"), brs_check(s, 10, interval = "right")) # Borders: score 0 -> delta 1 (F(u)), score 10 -> delta 2 (1 - F(l)) brs_check(c(0, 10), ncuts = 10)[, c("left", "right", "delta")] # A Likert item 1-5: shift to 0-4 so that K = ncuts = 4 is its maximum likert <- c(1, 2, 3, 5, 4) brs_check(likert - 1, ncuts = 4)[, c("left", "right", "delta")] # Unshifted, category 1 would be an interior cell and 0 a category never used brs_check(likert, ncuts = 5)[, "delta"] # Values already in (0, 1) are exact observations (delta 0) brs_check(c(0.12, 0.5, 0.97)) # Per observation: 0.3 is exact, 5 and 10 are scores (with a warning) brs_check(c(0.3, 5, 10), ncuts = 10) # A forced delta keeps the cell of the score brs_check(c(30, 60), ncuts = 100, delta = c(1L, 2L))
Deprecated convenience wrapper. Use brs_est for coefficient
estimates or summary.brs for a full model summary.
brs_coef(fit, alpha = 0.05)brs_coef(fit, alpha = 0.05)
fit |
A fitted |
alpha |
Significance level. |
A list with components est (from brs_est)
and gof (from brs_gof).
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) suppressWarnings(brs_coef(fit)) # deprecated; use brs_est()dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) suppressWarnings(brs_coef(fit)) # deprecated; use brs_est()
Performs repeated k-fold cross-validation for brs models.
brs_cv(formula, data, k = 5L, repeats = 1L, ...)brs_cv(formula, data, k = 5L, repeats = 1L, ...)
formula |
Model formula passed to |
data |
Data frame. |
k |
Number of folds. |
repeats |
Number of repeated k-fold runs. |
... |
Additional arguments forwarded to |
The log_score is the mean log predictive contribution under the
complete likelihood contribution implied by each observation's
censoring type (delta).
A data frame with one row per fold and columns:
repeat, fold, n_train, n_test,
log_score, rmse_yt, mae_yt, converged,
and error. The object has class "brs_cv".
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
# Synthetic NRS-11 scores: 4 groups x 3 times. Simulated, not real data. set.seed(3) nrs <- expand.grid(id = 1:40, time = c("6h", "12h", "24h")) nrs$group <- factor(paste0("g", (nrs$id - 1) %% 4 + 1)) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + c(0, -0.1, 0.05, 0.1)[nrs$group] shp <- brs_repar(mu = plogis(eta), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # 3-fold CV of two nested models, time only (m1) and time + group (m2); # log_score is the mean held-out log-likelihood contribution (higher is better) set.seed(5) cv1 <- brs_cv(y ~ time, data = nrs, k = 3, ncuts = 10) set.seed(5) cv2 <- brs_cv(y ~ time + group, data = nrs, k = 3, ncuts = 10) c(m1 = mean(cv1$log_score), m2 = mean(cv2$log_score)) cv2# Synthetic NRS-11 scores: 4 groups x 3 times. Simulated, not real data. set.seed(3) nrs <- expand.grid(id = 1:40, time = c("6h", "12h", "24h")) nrs$group <- factor(paste0("g", (nrs$id - 1) %% 4 + 1)) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + c(0, -0.1, 0.05, 0.1)[nrs$group] shp <- brs_repar(mu = plogis(eta), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # 3-fold CV of two nested models, time only (m1) and time + group (m2); # log_score is the mean held-out log-likelihood contribution (higher is better) set.seed(5) cv1 <- brs_cv(y ~ time, data = nrs, k = 3, ncuts = 10) set.seed(5) cv2 <- brs_cv(y ~ time + group, data = nrs, k = 3, ncuts = 10) c(m1 = mean(cv1$log_score), m2 = mean(cv2$log_score)) cv2
Coefficient estimates with inference
brs_est(object, alpha = 0.05)brs_est(object, alpha = 0.05)
object |
A fitted |
alpha |
Significance level (default 0.05). |
Data frame of estimates, standard errors, z-values, and p-values.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
brs, brs_gof, brs_hessian,
summary.brs
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) brs_est(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) brs_est(fit)
Goodness-of-fit measures
brs_gof(object)brs_gof(object)
object |
A fitted |
Data frame with logLik, AIC, BIC, and pseudo-R-squared.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) brs_gof(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) brs_gof(fit)
Extract the Hessian matrix
brs_hessian(object)brs_hessian(object)
object |
A fitted |
Numeric Hessian matrix.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) brs_hessian(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) brs_hessian(fit)
Computes average marginal effects (AME) for numeric covariates in the
mean or precision submodel of a fitted "brs" object.
brs_marginaleffects( object, newdata = NULL, model = c("mean", "precision"), type = c("response", "link"), variables = NULL, h = 1e-05, interval = TRUE, level = 0.95, n_sim = 400L, keep_draws = FALSE )brs_marginaleffects( object, newdata = NULL, model = c("mean", "precision"), type = c("response", "link"), variables = NULL, h = 1e-05, interval = TRUE, level = 0.95, n_sim = 400L, keep_draws = FALSE )
object |
A fitted |
newdata |
Optional data frame for evaluation; defaults to the data used in fitting. |
model |
Character; |
type |
Character prediction scale:
|
variables |
Optional character vector of covariate names. Defaults to all numeric covariates in the selected submodel. |
h |
Finite-difference step for non-binary numeric covariates. |
interval |
Logical; compute interval estimates via simulation. |
level |
Confidence level for interval estimates. |
n_sim |
Number of parameter draws when |
keep_draws |
Logical; if |
AMEs for a numeric covariate are computed by a central difference on predictions, with the step size scaled by the covariate's standard deviation:
where is the selected prediction scale and h is
the (small) base step supplied by the caller.
For binary covariates coded as 0/1, the effect is computed as the
average discrete difference .
If interval = TRUE, uncertainty is approximated by asymptotic
parameter simulation from .
A data frame with one row per variable and columns:
variable, ame, std.error, ci.lower,
ci.upper, model, type, and n.
The returned object has class "brs_marginaleffects" and
attributes with analysis metadata.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
# Synthetic NRS-11 scores with a 0/1 time dummy and a numeric covariate (age) set.seed(3) nrs <- data.frame(t12 = rep(0:1, each = 60), age = round(rnorm(120, 40, 12))) shp <- brs_repar(mu = plogis(-1.3 + 0.75 * nrs$t12 + 0.03 * (nrs$age - 40)), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) fit <- brs(y ~ t12 + age, data = nrs, ncuts = 10) # Average marginal effects on E[Y] (0/1 dummy: discrete change; age: slope), # with intervals from 50 draws of the estimates (use n_sim >= 400 in practice) set.seed(6) brs_marginaleffects(fit, n_sim = 50) # On the 0-10 score scale (mid cells): multiply by K = 10 set.seed(6) ame <- brs_marginaleffects(fit, n_sim = 50) transform(ame[, c("variable", "ame", "ci.lower", "ci.upper")], ame = 10 * ame, ci.lower = 10 * ci.lower, ci.upper = 10 * ci.upper)# Synthetic NRS-11 scores with a 0/1 time dummy and a numeric covariate (age) set.seed(3) nrs <- data.frame(t12 = rep(0:1, each = 60), age = round(rnorm(120, 40, 12))) shp <- brs_repar(mu = plogis(-1.3 + 0.75 * nrs$t12 + 0.03 * (nrs$age - 40)), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) fit <- brs(y ~ t12 + age, data = nrs, ncuts = 10) # Average marginal effects on E[Y] (0/1 dummy: discrete change; age: slope), # with intervals from 50 draws of the estimates (use n_sim >= 400 in practice) set.seed(6) brs_marginaleffects(fit, n_sim = 50) # On the 0-10 score scale (mid cells): multiply by K = 10 set.seed(6) ame <- brs_marginaleffects(fit, n_sim = 50) transform(ame[, c("variable", "ame", "ci.lower", "ci.upper")], ame = 10 * ame, ci.lower = 10 * ci.lower, ci.upper = 10 * ci.upper)
Computes predicted probabilities for integer scores on the original scale
implied by the fitted beta interval model.
brs_predict_scoreprob( object, newdata = NULL, scores = NULL, format = c("matrix", "long"), id_col = "id" )brs_predict_scoreprob( object, newdata = NULL, scores = NULL, format = c("matrix", "long"), id_col = "id" )
object |
A fitted |
newdata |
Optional data frame for prediction. |
scores |
Optional integer vector of scores to evaluate.
Defaults to all scores in |
format |
Output format: |
id_col |
Column name for observation id when |
For a score with cell of the fit's
interval (see brs_check), with and , where is the beta
CDF under the fitted . Under "mid" this is
for ,
for and
otherwise; under "right"/"left" the cells are
. The rows sum to 1 whenever the cells partition
(always for "right"/"left"; lim = 0.5
for "mid").
If format = "matrix", a numeric matrix with one row per
observation and one column per requested score.
If format = "long", a long data frame with columns
id_col, score, and prob.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), x2 = rep(c(0, 0, 1, 1), 5) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) pmat <- brs_predict_scoreprob(fit) head(pmat[, 1:5]) plong <- brs_predict_scoreprob(fit, scores = 0:10, format = "long") head(plong)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), x2 = rep(c(0, 0, 1, 1), 5) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) pmat <- brs_predict_scoreprob(fit) head(pmat[, 1:5]) plong <- brs_predict_scoreprob(fit, scores = 0:10, format = "long") head(plong)
Turns analyst data into the cells and censoring types
used by brs and brsmm. Scores
run over with ncuts the maximum;
shift a scale that starts at 1 (a Likert item 1–5 becomes 0–4,
ncuts = 4). Four input modes are recognised per row:
Score only (y): the cell of the score and
from the score, exactly as brs_check
(0 1, 2, otherwise 3; a value in
0, per observation).
Score and delta: the analyst's censoring type,
with the cell of the score.
Bounds only (left and/or right, y
missing): an interval, or a one-sided censoring when one bound is
NA.
Score and both bounds: the analyst's interval.
Covariate columns are kept unchanged.
brs_prep( data, y = "y", delta = "delta", left = "left", right = "right", ncuts = 100L, lim = 0.5, interval = c("mid", "right", "left") )brs_prep( data, y = "y", delta = "delta", left = "left", right = "right", ncuts = 100L, lim = 0.5, interval = c("mid", "right", "left") )
data |
Data frame with the response columns and covariates. |
y |
Character: name of the score column (default |
delta |
Character: name of the censoring-type column (default
|
left, right
|
Character: names of the lower and upper bound columns
(defaults |
ncuts |
Integer |
lim |
Numeric in |
interval |
Direction of the uncertainty interval, |
A non-missing delta always wins. Otherwise the type comes from
the pattern of left, right and y (here
, interval = "mid"):
left |
right |
y |
cell on
|
|
NA |
3 | NA |
(below 3) |
1 |
| 7 | NA |
NA |
(above 7)
|
2 |
| 2 | 5 | NA |
|
3 |
| 4 | 6 | 5 | (analyst interval) |
3 |
| -0.5 | 4 | NA |
(reaches 0) |
1 |
| 3 | 10.5 | NA |
(reaches 1)
|
2 |
| (no columns) | 5 | (Mode 1) |
3 | |
NA |
NA |
5 | 0.5 (exact reading) | 0 |
NA |
NA |
0 | |
1 |
NA |
NA |
10 | |
2 |
When the data have left/right columns, a row that gives
only an interior score (both bounds NA) is an exact value at the
cell centre, with a density contribution; without those columns the same
score is interval-censored (Mode 1). An analyst interval that reaches 0
(or 1) on the unit scale is left- (or right-) censored; one that reaches
both borders covers the whole scale, stays and gives a
warning, since such a row carries no information about the parameters.
A row with neither a score nor a bound is an error (a delta alone
defines no interval).
Score-based rows (Modes 1 and 2) use the cells of interval, as in
brs_check: for
"mid", for "right"/"left";
a forced keeps and a forced
keeps . Analyst bounds (Modes 3 and 4) are values of the
latent score of the chosen direction (the scale of
predict(type = "score")) and map to ("mid"),
("right") or ("left"),
so that the dissertation's intervals ,
and all give the cell of score .
They must lie in the latent range of the direction:
("mid"), ("right")
or ("left"); a bound outside it is an error. Rows
with no score get y = the latent score of their cell centre, so
that model.frame() keeps them.
Endpoints are clamped to ,
(why this replaces the edge-effect transformation
of Lopes, 2023: section 'Scale change and borders' of
brs_check). A row with left >= right
is an error (zero probability; use ), and so is a cell the
clamp squeezes to zero width (the message tells whether ncuts is
too large for the cells or the analyst interval lies inside the clamp).
As in brs_check, values in mixed with values
give one warning. Unusual combinations, e.g.
with , give a warning but are kept.
A data frame with columns left, right (cell on
), yt (cell centre), y (score, or the filled
latent score for rows without one) and delta, followed by the
covariates. Attributes "is_prepared" (TRUE),
"ncuts", "lim" and "interval" are reused by
brs and brsmm; an explicit different value
there is ignored with a warning.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
brs_check for the cells and the automatic
classification; brs for fitting the model.
# Mode 1: score only; delta from the score (0 -> 1, K -> 2, else 3) d1 <- data.frame(y = c(0, 3, 10), x = c(1.2, 0.4, -0.3)) brs_prep(d1, ncuts = 10) # Mode 2: score + analyst delta (the same score read as exact and as a cell) d2 <- data.frame(y = c(4, 4), delta = c(0, 3)) brs_prep(d2, ncuts = 10) # Mode 3: only left and/or right bounds (NA pattern gives delta) d3 <- data.frame(left = c(NA, 7, 2), right = c(3, NA, 5)) brs_prep(d3, ncuts = 10) # Mode 4: score with analyst bounds (used as given, divided by K) d4 <- data.frame(y = 5, left = 4, right = 6) brs_prep(d4, ncuts = 10) # An analyst interval reaching a border is one-sided censoring brs_prep(data.frame(left = c(-0.5, 3), right = c(4, 10.5)), ncuts = 10) # A Likert item 1-5: shift it to 0-4, so that ncuts = 4 is the maximum lk <- data.frame(item = c(1, 2, 5, 3, 4), x = c(0.1, 0.5, 0.9, 0.3, 0.7)) brs_prep(data.frame(y = lk$item - 1, x = lk$x), ncuts = 4) # Right-direction cells [s, s + 1] / 11; the choice is stored as attributes p <- brs_prep(d1, ncuts = 10, interval = "right") p[, c("left", "right", "delta")] attributes(p)[c("ncuts", "lim", "interval")]# Mode 1: score only; delta from the score (0 -> 1, K -> 2, else 3) d1 <- data.frame(y = c(0, 3, 10), x = c(1.2, 0.4, -0.3)) brs_prep(d1, ncuts = 10) # Mode 2: score + analyst delta (the same score read as exact and as a cell) d2 <- data.frame(y = c(4, 4), delta = c(0, 3)) brs_prep(d2, ncuts = 10) # Mode 3: only left and/or right bounds (NA pattern gives delta) d3 <- data.frame(left = c(NA, 7, 2), right = c(3, NA, 5)) brs_prep(d3, ncuts = 10) # Mode 4: score with analyst bounds (used as given, divided by K) d4 <- data.frame(y = 5, left = 4, right = 6) brs_prep(d4, ncuts = 10) # An analyst interval reaching a border is one-sided censoring brs_prep(data.frame(left = c(-0.5, 3), right = c(4, 10.5)), ncuts = 10) # A Likert item 1-5: shift it to 0-4, so that ncuts = 4 is the maximum lk <- data.frame(item = c(1, 2, 5, 3, 4), x = c(0.1, 0.5, 0.9, 0.3, 0.7)) brs_prep(data.frame(y = lk$item - 1, x = lk$x), ncuts = 4) # Right-direction cells [s, s + 1] / 11; the choice is stored as attributes p <- brs_prep(d1, ncuts = 10, interval = "right") p[, c("left", "right", "delta")] attributes(p)[c("ncuts", "lim", "interval")]
Converts the pair (mu, phi) of one of three parameterisations into
the shapes of the beta density
, .
brs_repar(mu, phi, repar = 2L)brs_repar(mu, phi, repar = 2L)
mu |
Numeric vector: the first parameter, i.e. the mean in
|
phi |
Numeric vector (or scalar): the second parameter, i.e. the
precision |
repar |
Integer (0, 1 or 2) selecting the scheme (default 2). |
repar |
mu, phi |
|
|
|
| 0 | shapes |
|
|
|
| 1 | mean , precision |
|
|
|
| 2 | mean , dispersion |
, |
|
|
The three describe the same family: is the precision, and the
dispersion of repar = 2 is
the share of the largest possible variance , which is
approached as . It is not a coefficient of variation.
In Lopes (2023) these are eq. eqn_beta_p1 (shapes ),
"parametrizacao 1" (Ferrari and Cribari-Neto, 2004; eq.
eqn_beta_p2) and "parametrizacao 2" (Bayer, 2011; eq.
eqn_beta_p3), where the dispersion is written . The
package names the second parameter phi in every scheme. Regression
on the shapes (repar = 0) is a package extension. Admissible links
per scheme: section 'Reparameterizations and links' of brs.
A data.frame with columns shape1 () and
shape2 (), one row per element of the recycled inputs.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
Bayer, F. M. (2011). Modelagem e inferencia em regressao beta. PhD thesis, Universidade Federal de Pernambuco.
# One beta distribution in the three parameterisations: shapes (6, 14) brs_repar(mu = 0.3, phi = 20, repar = 1) # mean 0.3, precision 20 brs_repar(mu = 0.3, phi = 1 / 21, repar = 2) # mean 0.3, dispersion 1/(1 + 20) brs_repar(mu = 6, phi = 14, repar = 0) # shapes p = 6, q = 14 # Back from shapes: mean, precision a + b, dispersion 1 / (1 + a + b) sh <- brs_repar(mu = 0.3, phi = 20, repar = 1) c(mean = sh$shape1 / (sh$shape1 + sh$shape2), precision = sh$shape1 + sh$shape2, dispersion = 1 / (1 + sh$shape1 + sh$shape2)) # E[Y] and Var[Y] agree across parameterisations: 0.3 and 0.21 / 21 = 0.01 mu <- 0.3 c(var_repar1 = mu * (1 - mu) / (1 + 20), var_repar2 = mu * (1 - mu) * (1 / 21), var_shapes = 6 * 14 / ((6 + 14)^2 * (6 + 14 + 1))) # Vectorised: one row per observation brs_repar(mu = c(0.2, 0.5, 0.8), phi = 0.1, repar = 2)# One beta distribution in the three parameterisations: shapes (6, 14) brs_repar(mu = 0.3, phi = 20, repar = 1) # mean 0.3, precision 20 brs_repar(mu = 0.3, phi = 1 / 21, repar = 2) # mean 0.3, dispersion 1/(1 + 20) brs_repar(mu = 6, phi = 14, repar = 0) # shapes p = 6, q = 14 # Back from shapes: mean, precision a + b, dispersion 1 / (1 + a + b) sh <- brs_repar(mu = 0.3, phi = 20, repar = 1) c(mean = sh$shape1 / (sh$shape1 + sh$shape2), precision = sh$shape1 + sh$shape2, dispersion = 1 / (1 + sh$shape1 + sh$shape2)) # E[Y] and Var[Y] agree across parameterisations: 0.3 and 0.21 / 21 = 0.01 mu <- 0.3 c(var_repar1 = mu * (1 - mu) / (1 + 20), var_repar2 = mu * (1 - mu) * (1 / 21), var_shapes = 6 * 14 / ((6 + 14)^2 * (6 + 14 + 1))) # Vectorised: one row per observation brs_repar(mu = c(0.2, 0.5, 0.8), phi = 0.1, repar = 2)
Simulates scores on ( ncuts) from a
fixed- or variable-dispersion beta regression, coarsened exactly as the
likelihood of brs assumes. The output can be passed to
brs as it is.
brs_sim( formula, data, beta, phi = 1/5, zeta = NULL, link = NULL, link_phi = NULL, ncuts = 100L, lim = 0.5, repar = 2L, delta = NULL, interval = c("mid", "right", "left") )brs_sim( formula, data, beta, phi = 1/5, zeta = NULL, link = NULL, link_phi = NULL, ncuts = 100L, lim = 0.5, repar = 2L, delta = NULL, interval = c("mid", "right", "left") )
formula |
Model formula with one (mean) or two parts
(mean |
data |
Data frame with the covariates. |
beta |
Coefficients of the first parameter, on its link scale. |
phi |
Second parameter on its link scale (one-part formulas). |
zeta |
Coefficients of the second parameter, on its link scale (two-part formulas). |
link, link_phi
|
Links; |
ncuts |
Integer |
lim |
Half-width of the cell under |
repar |
Parameterisation (0, 1 or 2); see |
delta |
|
interval |
|
formula follows brs: a one-part formula
(~ x1 + x2) uses the scalar phi, a two-part formula
(~ x1 + x2 | z1) the coefficients zeta. A left-hand side is
ignored. For each row, with the shapes of
brs_repar, and the score is
under "mid" (cells centred on the score; exact only for
lim = 0.5) or under
"right"/"left" ( equal cells). The cells and
censoring types then come from brs_check with the same
interval: 0 is left-censored, right-censored, the rest
interval-censored. Censoring is therefore non-informative: the cells are
fixed and do not depend on .
delta overrides the type for every row: 0 keeps the
continuous as exact values; 3 keeps the scores away from
the borders (); 1 or 2 censors every
row on one side at the cell of its own score. The last two make the
threshold depend on (informative censoring): the likelihood has no
finite maximum and brs returns diverging coefficients, with
clamp warnings. brs_sim() warns in that case, and also whenever all
simulated rows fall on the same border.
A Monte Carlo study in the design of Lopes (2023, ch. 3) is a loop of
brs_sim() and brs() over a fixed design; see the vignette
vignette("brs-advanced-workflows").
A data frame with columns left, right, yt,
y (score), delta and the non-intercept columns of the model
matrices, with the attributes "is_prepared", "ncuts",
"lim" and "interval" that brs reuses.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
brs, brs_check,
brs_repar, brs_bootstrap
# One design, three parameterisations with their default links set.seed(42) d <- data.frame(x = rnorm(300)) # repar = 2 (logit/logit): mean and dispersion on (0, 1) s2 <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = qlogis(0.2), ncuts = 10) f2 <- brs(y ~ x, data = s2) round(cbind(true = c(0.3, 0.6, qlogis(0.2)), est = coef(f2)), 2) # repar = 1 (logit/log): precision 20 s1 <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = log(20), ncuts = 10, repar = 1) f1 <- brs(y ~ x, data = s1, repar = 1) round(cbind(true = c(0.3, 0.6, log(20)), est = coef(f1)), 2) # repar = 0 (log/log): shapes p = 3 exp(0.3 x), q = 2 s0 <- brs_sim(~ x, data = d, beta = c(log(3), 0.3), phi = log(2), ncuts = 10, repar = 0) f0 <- brs(y ~ x, data = s0, repar = 0) round(cbind(true = c(log(3), 0.3, log(2)), est = coef(f0)), 2) # The output is ready for brs(): endpoints, delta and attributes head(s2) attributes(s2)[c("ncuts", "lim", "interval")] # Right-direction cells: scores drawn as floor(11 * Y) sr <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = qlogis(0.2), ncuts = 10, interval = "right") table(sr$delta) # Forcing delta = 1 on every row is informative censoring: a warning sl <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = qlogis(0.2), ncuts = 10, delta = 1) table(sl$delta)# One design, three parameterisations with their default links set.seed(42) d <- data.frame(x = rnorm(300)) # repar = 2 (logit/logit): mean and dispersion on (0, 1) s2 <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = qlogis(0.2), ncuts = 10) f2 <- brs(y ~ x, data = s2) round(cbind(true = c(0.3, 0.6, qlogis(0.2)), est = coef(f2)), 2) # repar = 1 (logit/log): precision 20 s1 <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = log(20), ncuts = 10, repar = 1) f1 <- brs(y ~ x, data = s1, repar = 1) round(cbind(true = c(0.3, 0.6, log(20)), est = coef(f1)), 2) # repar = 0 (log/log): shapes p = 3 exp(0.3 x), q = 2 s0 <- brs_sim(~ x, data = d, beta = c(log(3), 0.3), phi = log(2), ncuts = 10, repar = 0) f0 <- brs(y ~ x, data = s0, repar = 0) round(cbind(true = c(log(3), 0.3, log(2)), est = coef(f0)), 2) # The output is ready for brs(): endpoints, delta and attributes head(s2) attributes(s2)[c("ncuts", "lim", "interval")] # Right-direction cells: scores drawn as floor(11 * Y) sr <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = qlogis(0.2), ncuts = 10, interval = "right") table(sr$delta) # Forcing delta = 1 on every row is informative censoring: a warning sl <- brs_sim(~ x, data = d, beta = c(0.3, 0.6), phi = qlogis(0.2), ncuts = 10, delta = 1) table(sl$delta)
Builds a comparison table for one or more fitted "brs" or
"brsmm" objects, summarizing fit statistics and (optionally)
censoring composition. Models of both classes may be mixed in the same
call.
brs_table( ..., models = NULL, include_censoring = TRUE, sort_by = c("none", "AIC", "BIC", "logLik"), decreasing = FALSE, digits = 4L )brs_table( ..., models = NULL, include_censoring = TRUE, sort_by = c("none", "AIC", "BIC", "logLik"), decreasing = FALSE, digits = 4L )
... |
Fitted |
models |
Optional list of fitted |
include_censoring |
Logical; include censoring counts/proportions.
Default is |
sort_by |
Character; optional sort criterion:
|
decreasing |
Logical; sort direction when |
digits |
Integer number of digits used for numeric rounding. |
A data frame with one row per model.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Hawker, G. A., Mian, S., Kendzerska, T., and French, M. (2011). Measures of adult pain: Visual Analog Scale for Pain (VAS Pain), Numeric Rating Scale for Pain (NRS Pain), McGill Pain Questionnaire (MPQ), Short-Form McGill Pain Questionnaire (SF-MPQ), Chronic Pain Grade Scale (CPGS), Short Form-36 Bodily Pain Scale (SF-36 BPS), and Measure of Intermittent and Constant Osteoarthritis Pain (ICOAP). Arthritis Care and Research, 63(S11), S240-S252. doi:10.1002/acr.20543
Hjermstad, M. J., Fayers, P. M., Haugen, D. F., et al. (2011). Studies comparing Numerical Rating Scales, Verbal Rating Scales, and Visual Analogue Scales for assessment of pain intensity in adults: a systematic literature review. Journal of Pain and Symptom Management, 41(6), 1073-1093. doi:10.1016/j.jpainsymman.2010.08.016
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), x2 = rep(c(0, 0, 1, 1), 5) ) prep <- brs_prep(dat, ncuts = 100) m1 <- brs(y ~ 1, data = prep) m2 <- brs(y ~ x1, data = prep) brs_table(null = m1, x1 = m2, sort_by = "AIC")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), x2 = rep(c(0, 0, 1, 1), 5) ) prep <- brs_prep(dat, ncuts = 100) m1 <- brs(y ~ 1, data = prep) m2 <- brs(y ~ x1, data = prep) brs_table(null = m1, x1 = m2, sort_by = "AIC")
Beta interval regression (brs) with Gaussian random effects
in the linear predictor of the first parameter (the mean, or the shape
under repar = 0), fitted by marginal maximum likelihood.
random = ~ 1 | id gives a random intercept per group,
~ 1 + x | id a random intercept and slope with a free correlation.
brsmm( formula, random = ~1 | id, data, link = NULL, link_phi = NULL, repar = 2L, ncuts = NULL, lim = NULL, int_method = c("laplace", "aghq", "qmc"), n_points = 11L, qmc_points = 1024L, start = NULL, method = c("BFGS", "L-BFGS-B"), hessian_method = c("cpp", "numDeriv", "optim"), control = list(maxit = 2000L), interval = NULL )brsmm( formula, random = ~1 | id, data, link = NULL, link_phi = NULL, repar = 2L, ncuts = NULL, lim = NULL, int_method = c("laplace", "aghq", "qmc"), n_points = 11L, qmc_points = 1024L, start = NULL, method = c("BFGS", "L-BFGS-B"), hessian_method = c("cpp", "numDeriv", "optim"), control = list(maxit = 2000L), interval = NULL )
formula |
Model formula: |
random |
Random-effects formula |
data |
Data frame (raw scores, or the output of
|
link, link_phi
|
Links for the first and second parameter;
|
repar |
Parameterisation (0, 1 or 2); see |
ncuts |
Integer |
lim |
Half-width of the cell in |
int_method |
|
n_points |
Nodes per dimension for |
qmc_points |
Halton points for |
start |
Optional starting vector: fixed effects, precision coefficients, then the packed Cholesky parameters. |
method |
|
hessian_method |
|
control |
Control list for |
interval |
|
For group with observations , the model is
with the censored contributions of brs. The marginal
log-likelihood is , where
. The integral
is computed around the mode of , with
there:
"laplace"; fast, accurate when groups are not tiny.
"aghq"adaptive Gauss-Hermite quadrature: a product grid of
n_points nodes per dimension at
, with the symmetric square
root (n_points nodes, at most
500000).
"qmc"importance sampling from
(nodes ) on qmc_points Halton
points. It is deterministic and, with two or more random effects,
underestimates the log-likelihood (about at 1024 points
in the package's two-effect checks); prefer "aghq" for up to
three random effects.
The inner mode is found by a Levenberg–Marquardt Newton method,
warm-started from the modes of the previous evaluation (the cache is
cleared at the start of each fit). A group whose curvature is not positive
definite at its mode adds the penalty value instead of a
silently regularised term, and brsmm() warns.
is parameterised by its lower Cholesky factor: the
log of each diagonal entry and the off-diagonal entries as they are
((re_chol_logsd)_ and (re_chol)_ in coef()).
summary.brsmm reports the standard deviations and
correlations with intervals; brsmm_re_study the intraclass
correlation.
An object of class "brsmm" with the components of a
"brs" fit (par, coefficients with a random
part, value, hessian, diagnostics, ...) and
random (group variable, levels, conditional modes mode_b,
D, L and the SDs sd_b), ngroups,
int_method.
optim maximises the marginal log-likelihood with its
compiled gradient: the derivative of the chosen approximation by the chain
rule on the linear predictor and the implicit-function theorem at the group
modes (including the movement of the quadrature nodes), with
per-observation derivatives by central differences. The Hessian for
vcov() (hessian_method = "cpp", the default) is a Richardson
central difference of that gradient. Starting values: start when
given; otherwise those of brs for the fixed effects and
of the between-group SD of the cell centres (at least 0.1) for
the random effects.
The checks of brs ('Fit diagnostics') apply, with the
compiled gradient (a central difference with step if it is
not finite). In addition:
A random-effect term
has log SD below , or raises the log-likelihood by less than
over the same fit with that SD at zero. Its variance is
essentially zero; the standard error of its log SD is meaningless. Test
the term with anova.brsmm (chi-bar-square mixture) and
drop it if not needed. When the gain is negative the message adds that
SD has a higher log-likelihood: optim stopped
short of the maximum.
Those groups contribute the penalty value; the fit is not reliable. Simplify the random-effects structure or check the data of those groups.
fit$diagnostics stores re_boundary, re_gain and
inner (number of such groups, largest gradient norm at the modes).
Rank-deficient fixed-effect or random-effect design matrices are an error.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
Pinheiro, J. C., and Bates, D. M. (1995). Approximations to the log-likelihood function in the nonlinear mixed-effects model. Journal of Computational and Graphical Statistics, 4(1), 12–35. doi:10.1080/10618600.1995.10474663
brs, summary.brsmm,
anova.brsmm, brsmm_re_study,
ranef.brsmm, predict.brsmm
# Synthetic NRS-11 scores (0-10) of 40 patients at 6h, 12h and 24h; # intercepts and time slopes vary by patient. Simulated, not real data. set.seed(21) nrs <- expand.grid(id = 1:40, time = c("6h", "12h", "24h")) nrs$tc <- c(-1, 0, 1)[nrs$time] # centred time for the slope b0 <- rnorm(40, sd = 0.8) b1 <- rnorm(40, sd = 0.5) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + b0[nrs$id] + b1[nrs$id] * nrs$tc shp <- brs_repar(mu = plogis(eta), phi = 0.2, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # Random intercept per patient (Laplace): SD with its interval, no z-test m1 <- brsmm(y ~ time, random = ~ 1 | id, data = nrs, ncuts = 10) summary(m1) # Random intercept and slope: SDs and their correlation m2 <- brsmm(y ~ time, random = ~ 1 + tc | id, data = nrs, ncuts = 10) summary(m2)$varcorr head(ranef(m2)) # Is the slope needed? One added random term: the p-value uses the # mixture 1/2 chi2(1) + 1/2 chi2(2) (see the printed heading) anova(m1, m2) # A known patient uses its conditional mode; a new one gets b = 0 nd <- data.frame(time = "12h", tc = 0, id = c(1, 999)) predict(m2, newdata = nd)# Synthetic NRS-11 scores (0-10) of 40 patients at 6h, 12h and 24h; # intercepts and time slopes vary by patient. Simulated, not real data. set.seed(21) nrs <- expand.grid(id = 1:40, time = c("6h", "12h", "24h")) nrs$tc <- c(-1, 0, 1)[nrs$time] # centred time for the slope b0 <- rnorm(40, sd = 0.8) b1 <- rnorm(40, sd = 0.5) eta <- -1.3 + c(0, 0.75, 0.3)[nrs$time] + b0[nrs$id] + b1[nrs$id] * nrs$tc shp <- brs_repar(mu = plogis(eta), phi = 0.2, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) # Random intercept per patient (Laplace): SD with its interval, no z-test m1 <- brsmm(y ~ time, random = ~ 1 | id, data = nrs, ncuts = 10) summary(m1) # Random intercept and slope: SDs and their correlation m2 <- brsmm(y ~ time, random = ~ 1 + tc | id, data = nrs, ncuts = 10) summary(m2)$varcorr head(ranef(m2)) # Is the slope needed? One added random term: the p-value uses the # mixture 1/2 chi2(1) + 1/2 chi2(2) (see the printed heading) anova(m1, m2) # A known patient uses its conditional mode; a new one gets b = 0 nd <- data.frame(time = "12h", tc = 0, id = c(1, 999)) predict(m2, newdata = nd)
Provides a compact numeric study of random effects, including: estimated covariance matrix, correlation matrix, per-term standard deviations, empirical mean/SD of posterior modes, shrinkage ratio, and a normality check by Shapiro-Wilk (when applicable).
brsmm_re_study(object, ...)brsmm_re_study(object, ...)
object |
A fitted |
... |
Currently ignored. |
icc is the intraclass correlation of implied
by the fitted model: for two observations of the same group with the
covariates of observation ,
where are the beta shapes with random part
, and ,
are the digamma and trigamma functions
(,
). The
expectations over use 40-point Gauss-Hermite quadrature and the
reported value is the mean of over the observations.
The level-1 variance is that of the beta, so the value depends on the
precision; with the logit link (only) and a large precision it approaches
. It replaces the
logistic-latent formula , which
does not describe a beta response.
The moments of over can be infinite: with a
probit link when , with a cloglog link for every
, and numerically with any link when is
very large. The value would then be set by the clamp of the mean
(), so icc is NA, with a warning, whenever
changes by more than 10% when that clamp
is tightened to .
A list with class "brsmm_re_study".
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) rs <- brsmm_re_study(fit) print(rs) rs$summarydat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) rs <- brsmm_re_study(fit) print(rs) rs$summary
Extract model coefficients
## S3 method for class 'brs' coef(object, model = c("full", "mean", "precision"), ...)## S3 method for class 'brs' coef(object, model = c("full", "mean", "precision"), ...)
object |
A fitted |
model |
Character: which component to return.
|
... |
Ignored. |
Named numeric vector of estimated parameters.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) coef(fit) coef(fit, model = "mean") coef(fit, model = "precision")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) coef(fit) coef(fit, model = "mean") coef(fit, model = "precision")
Extract coefficients from a brsmm fit
## S3 method for class 'brsmm' coef(object, model = c("full", "mean", "precision", "random"), ...)## S3 method for class 'brsmm' coef(object, model = c("full", "mean", "precision", "random"), ...)
object |
A fitted |
model |
Character: |
... |
Currently ignored. |
Named numeric vector.
brsmm, vcov.brsmm,
confint.brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) coef(fit) coef(fit, model = "mean") coef(fit, model = "random")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) coef(fit) coef(fit, model = "mean") coef(fit, model = "random")
Wald intervals on the link
scale, with from vcov.brs (Lopes, 2023,
"Inferencia").
## S3 method for class 'brs' confint( object, parm, level = 0.95, model = c("full", "mean", "precision"), ... )## S3 method for class 'brs' confint( object, parm, level = 0.95, model = c("full", "mean", "precision"), ... )
object |
A fitted |
parm |
Character or integer: which parameters. If missing, all
parameters of |
level |
Confidence level (default 0.95). |
model |
Character: |
... |
Currently ignored. |
Intervals for a mean or precision on the response scale follow by the
inverse link of the limits (monotone links). A limit is NA when the
variance is not estimable (see 'Fit diagnostics' in brs).
For small samples or parameters near the border of the scale,
brs_bootstrap gives intervals that do not rely on the normal
approximation.
Matrix with the lower and upper limits.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
brs, vcov.brs,
brs_bootstrap, brs_est
set.seed(2023) d <- data.frame(x = runif(150)) s <- brs_sim(~ x, data = d, beta = c(-0.5, 1), phi = qlogis(0.3), ncuts = 10) fit <- brs(y ~ x, data = s) confint(fit) # Mean at x = 0 on (0, 1): inverse logit of the intercept limits plogis(confint(fit, parm = "(Intercept)"))set.seed(2023) d <- data.frame(x = runif(150)) s <- brs_sim(~ x, data = d, beta = c(-0.5, 1), phi = qlogis(0.3), ncuts = 10) fit <- brs(y ~ x, data = s) confint(fit) # Mean at x = 0 on (0, 1): inverse logit of the intercept limits plogis(confint(fit, parm = "(Intercept)"))
Wald confidence intervals for brsmm models
## S3 method for class 'brsmm' confint( object, parm, level = 0.95, model = c("full", "mean", "precision", "random"), ... )## S3 method for class 'brsmm' confint( object, parm, level = 0.95, model = c("full", "mean", "precision", "random"), ... )
object |
A fitted |
parm |
Character or integer: which parameters. |
level |
Confidence level (default 0.95). |
model |
Character: |
... |
Currently ignored. |
Matrix with columns for lower and upper confidence bounds.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) confint(fit, model = "mean")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) confint(fit, model = "mean")
Extract fitted values
## S3 method for class 'brs' fitted(object, type = c("mu", "phi"), ...)## S3 method for class 'brs' fitted(object, type = c("mu", "phi"), ...)
object |
A fitted |
type |
Character: |
... |
Currently ignored. |
Numeric vector of fitted values.
brs, residuals.brs,
predict.brs
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) head(fitted(fit)) head(fitted(fit, type = "phi"))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) head(fitted(fit)) head(fitted(fit, type = "phi"))
Fitted values from a brsmm model
## S3 method for class 'brsmm' fitted(object, type = c("mu", "phi"), ...)## S3 method for class 'brsmm' fitted(object, type = c("mu", "phi"), ...)
object |
A fitted |
type |
Character: |
... |
Currently ignored. |
Numeric vector.
brsmm, residuals.brsmm,
predict.brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(fitted(fit)) head(fitted(fit, type = "phi"))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(fitted(fit)) head(fitted(fit, type = "phi"))
Extract model formula
## S3 method for class 'brs' formula(x, ...)## S3 method for class 'brs' formula(x, ...)
x |
A fitted |
... |
Ignored. |
The formula used to fit the model.
brs, model.matrix.brs,
coef.brs
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) formula(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) formula(fit)
Extract model formula
## S3 method for class 'brsmm' formula(x, ...)## S3 method for class 'brsmm' formula(x, ...)
x |
A fitted |
... |
Ignored. |
The formula used to fit the model.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) formula(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) formula(fit)
Extract log-likelihood
## S3 method for class 'brs' logLik(object, ...)## S3 method for class 'brs' logLik(object, ...)
object |
A fitted |
... |
Ignored. |
An object of class "logLik" with attributes
df (number of estimated parameters) and nobs
(number of observations).
brs, AIC.brs, BIC.brs,
brs_gof
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) logLik(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) logLik(fit)
Log-likelihood for brsmm models
## S3 method for class 'brsmm' logLik(object, ...)## S3 method for class 'brsmm' logLik(object, ...)
object |
A fitted |
... |
Currently ignored. |
Object of class "logLik".
brsmm, AIC.brsmm,
BIC.brsmm, brs_gof
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) logLik(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) logLik(fit)
Extract design matrix
## S3 method for class 'brs' model.matrix(object, model = c("mean", "precision"), ...)## S3 method for class 'brs' model.matrix(object, model = c("mean", "precision"), ...)
object |
A fitted |
model |
Character: |
... |
Ignored. |
The design matrix for the specified submodel.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) head(model.matrix(fit)) head(model.matrix(fit, model = "precision"))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) head(model.matrix(fit)) head(model.matrix(fit, model = "precision"))
Extract design matrix
## S3 method for class 'brsmm' model.matrix(object, model = c("mean", "precision", "random"), ...)## S3 method for class 'brsmm' model.matrix(object, model = c("mean", "precision", "random"), ...)
object |
A fitted |
model |
Character: |
... |
Ignored. |
The design matrix for the specified submodel.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(model.matrix(fit)) head(model.matrix(fit, model = "random"))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(model.matrix(fit)) head(model.matrix(fit, model = "random"))
Number of observations
## S3 method for class 'brs' nobs(object, ...)## S3 method for class 'brs' nobs(object, ...)
object |
A fitted |
... |
Ignored. |
Integer: number of observations.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) nobs(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) nobs(fit)
Number of observations in a brsmm fit
## S3 method for class 'brsmm' nobs(object, ...)## S3 method for class 'brsmm' nobs(object, ...)
object |
A fitted |
... |
Currently ignored. |
Integer.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) nobs(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) nobs(fit)
Produces up to six diagnostic plots for a fitted
"brs" model: residuals vs indices, Cook's
distance, residuals vs linear predictor, residuals vs fitted
values, a half-normal plot with simulated envelope, and
predicted vs observed.
## S3 method for class 'brs' plot( x, which = 1:4, type = "rqr", nsim = 100L, level = 0.9, caption = c("Residuals vs indices", "Cook's distance", "Residuals vs linear predictor", "Residuals vs fitted values", "Half-normal plot", "Predicted vs observed"), sub.caption = NULL, ask = prod(par("mfcol")) < length(which) && dev.interactive(), gg = FALSE, title = NULL, theme = NULL, ... )## S3 method for class 'brs' plot( x, which = 1:4, type = "rqr", nsim = 100L, level = 0.9, caption = c("Residuals vs indices", "Cook's distance", "Residuals vs linear predictor", "Residuals vs fitted values", "Half-normal plot", "Predicted vs observed"), sub.caption = NULL, ask = prod(par("mfcol")) < length(which) && dev.interactive(), gg = FALSE, title = NULL, theme = NULL, ... )
x |
A fitted |
which |
Integer vector selecting which plots to draw
(default |
type |
Character: residual type passed to
|
nsim |
Integer: number of simulations for the half-normal envelope (default 100). |
level |
Numeric: confidence level for the envelope (default 0.9). |
caption |
Character vector of panel captions. |
sub.caption |
Subtitle; defaults to the model call. |
ask |
Logical: prompt before each page of plots? |
gg |
Logical: use ggplot2? (default |
title |
Optional global title for ggplot output. If |
theme |
Optional ggplot2 theme object (e.g., |
... |
Further arguments passed to base |
Invisibly returns x.
brs, residuals.brs,
autoplot.brs
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) plot(fit, which = 1:4)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) plot(fit, which = 1:4)
Produces diagnostic plots for fitted "brsmm" models:
residuals vs indices, Cook's distance, residuals vs linear predictor,
residuals vs fitted values, half-normal envelope, and predicted vs observed.
## S3 method for class 'brsmm' plot( x, which = 1:4, type = c("response", "pearson"), nsim = 100L, level = 0.9, caption = c("Residuals vs indices", "Cook's distance", "Residuals vs linear predictor", "Residuals vs fitted values", "Half-normal plot", "Predicted vs observed", "Random-effects Q-Q", "Random-effects caterpillar"), sub.caption = NULL, ask = prod(par("mfcol")) < length(which) && dev.interactive(), gg = FALSE, title = NULL, theme = NULL, ... )## S3 method for class 'brsmm' plot( x, which = 1:4, type = c("response", "pearson"), nsim = 100L, level = 0.9, caption = c("Residuals vs indices", "Cook's distance", "Residuals vs linear predictor", "Residuals vs fitted values", "Half-normal plot", "Predicted vs observed", "Random-effects Q-Q", "Random-effects caterpillar"), sub.caption = NULL, ask = prod(par("mfcol")) < length(which) && dev.interactive(), gg = FALSE, title = NULL, theme = NULL, ... )
x |
A fitted |
which |
Integer vector selecting which panels to draw
(default |
type |
Residual type passed to |
nsim |
Number of simulations for half-normal envelope. |
level |
Confidence level for the half-normal envelope. |
caption |
Character vector of plot captions. |
sub.caption |
Optional subtitle; defaults to model call. |
ask |
Logical: prompt before each new page? |
gg |
Logical: use ggplot2 backend? |
title |
Optional global title for ggplot output. If |
theme |
Optional ggplot2 theme object (e.g., |
... |
Further arguments passed to base |
Invisibly returns x.
brsmm, residuals.brsmm,
autoplot.brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) plot(fit, which = 1:4)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) plot(fit, which = 1:4)
Predict from a fitted model
## S3 method for class 'brs' predict( object, newdata = NULL, type = c("response", "link", "precision", "variance", "quantile", "score", "expected_score"), at = 0.5, ... )## S3 method for class 'brs' predict( object, newdata = NULL, type = c("response", "link", "precision", "variance", "quantile", "score", "expected_score"), at = 0.5, ... )
object |
A fitted |
newdata |
Optional data frame for prediction. |
type |
Prediction type: |
at |
Numeric vector of probabilities for quantile predictions (default 0.5). |
... |
Currently ignored. |
Numeric vector or matrix.
brs, fitted.brs,
brs_predict_scoreprob
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) head(predict(fit)) head(predict(fit, type = "precision")) newdat <- data.frame(x1 = c(1, 2)) predict(fit, newdata = newdat)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) head(predict(fit)) head(predict(fit, type = "precision")) newdat <- data.frame(x1 = c(1, 2)) predict(fit, newdata = newdat)
Predict from a brsmm model
## S3 method for class 'brsmm' predict( object, newdata = NULL, type = c("response", "link", "precision", "variance", "quantile", "score", "expected_score"), at = 0.5, ... )## S3 method for class 'brsmm' predict( object, newdata = NULL, type = c("response", "link", "precision", "variance", "quantile", "score", "expected_score"), at = 0.5, ... )
object |
A fitted |
newdata |
Optional data frame. |
type |
Character: |
at |
Numeric vector of probabilities for quantile predictions (default 0.5). |
... |
Currently ignored. |
Numeric vector, except when type = "quantile" and
at has length greater than 1, in which case a numeric matrix
with one column per requested quantile (named q_<value>, e.g.
"q_0.5") and one row per observation.
brsmm, fitted.brsmm,
brs_predict_scoreprob
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(predict(fit)) head(predict(fit, type = "precision"))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(predict(fit)) head(predict(fit, type = "precision"))
Print a fitted model (brief betareg style)
## S3 method for class 'brs' print(x, digits = max(3, getOption("digits") - 3), ...)## S3 method for class 'brs' print(x, digits = max(3, getOption("digits") - 3), ...)
x |
A fitted |
digits |
Number of significant digits. |
... |
Included for consistency with generic methods. Currently passed to internal methods where applicable. |
Invisibly returns the input object x. The function is called
for its side effect of printing a formatted summary of the fitted model
to the console, including the model call, mean coefficients (with link
function), and precision coefficients (with link function).
summary.brs, print.summary.brs,
brs
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) print(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) print(fit)
Print a fitted brsmm model
## S3 method for class 'brsmm' print(x, digits = max(3, getOption("digits") - 3), ...)## S3 method for class 'brsmm' print(x, digits = max(3, getOption("digits") - 3), ...)
x |
A fitted |
digits |
Number of digits. |
... |
Included for consistency with generic methods. |
Invisibly returns x.
summary.brsmm, print.summary.brsmm,
brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) print(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) print(fit)
Prints a compact summary of the random-effects study returned by
brsmm_re_study, including per-term standard deviations,
shrinkage ratios, Shapiro-Wilk p-values, and the estimated covariance
and correlation matrices.
## S3 method for class 'brsmm_re_study' print(x, digits = max(3, getOption("digits") - 3), ...)## S3 method for class 'brsmm_re_study' print(x, digits = max(3, getOption("digits") - 3), ...)
x |
A |
digits |
Integer: number of significant digits for rounding
(default |
... |
Currently ignored. |
Invisibly returns x. Called for its side-effect of
printing the study to the console.
brsmm_re_study, brsmm,
ranef.brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) rs <- brsmm_re_study(fit) print(rs)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) rs <- brsmm_re_study(fit) print(rs)
Print a model summary (betareg style)
## S3 method for class 'summary.brs' print(x, digits = max(3, getOption("digits") - 3), ...)## S3 method for class 'summary.brs' print(x, digits = max(3, getOption("digits") - 3), ...)
x |
A |
digits |
Number of digits. |
... |
Passed to |
Invisibly returns the input object x. The function is called
for its side effect of printing a comprehensive summary to the console,
including the model call, quantile residuals, coefficient tables for mean
and precision submodels with significance stars, goodness-of-fit statistics
(log-likelihood, pseudo R-squared), optimization details, and censoring
information.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) print(summary(fit))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) print(summary(fit))
Print summary for brsmm models
## S3 method for class 'summary.brsmm' print(x, digits = max(3, getOption("digits") - 3), ...)## S3 method for class 'summary.brsmm' print(x, digits = max(3, getOption("digits") - 3), ...)
x |
A |
digits |
Number of digits. |
... |
Passed to |
Invisibly returns x.
summary.brsmm, brsmm,
print.brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) print(summary(fit))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) print(summary(fit))
Generic function for extracting random effects.
ranef(object, ...)ranef(object, ...)
object |
A fitted model object. |
... |
Additional arguments passed to methods. |
Method-specific; for "brsmm" objects, a matrix or named
numeric vector of group-specific random-effect modes.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) ranef(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) ranef(fit)
Extract random effects from a brsmm model
## S3 method for class 'brsmm' ranef(object, ...)## S3 method for class 'brsmm' ranef(object, ...)
object |
A fitted |
... |
Currently ignored. |
A matrix or named numeric vector of group-specific random-effect posterior modes.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) ranef(fit)dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) ranef(fit)
Residuals of a "brs" fit. Randomized quantile residuals
(type = "rqr") use the censoring of each observation and are the
recommended ones; the other types are evaluated at one point of the cell
(see Details).
## S3 method for class 'brs' residuals( object, type = c("response", "pearson", "deviance", "rqr", "weighted", "sweighted"), ... )## S3 method for class 'brs' residuals( object, type = c("response", "pearson", "deviance", "rqr", "weighted", "sweighted"), ... )
object |
A fitted |
type |
Residual type: |
... |
Currently ignored. |
Let be the fitted shapes,
the fitted mean and the fitted variance (brs_repar).
All types except "rqr" use yt, the centre of the
cell: under interval = "mid", so that the border scores
sit at and , and
under "right"/"left"; exact values are used as they are. This
is the midpoint convention of Lopes (2023, "Analise de residuos"); it makes
these residuals unreliable at the borders of the scale.
"response".
"pearson". Lopes (2023)
writes as
(parameterisation 1); it is the same variance under every
repar.
"deviance", where is
the beta log-density at with mean and precision
(Ferrari and Cribari-Neto, 2004). The saturated mean
is taken as , as in betareg. For a small precision
(U- or J-shaped densities) can be below
; the absolute value is then used and only the
sign carries information.
"rqr", with uniform on
for , on for
and on for , and
for exact values (Dunn and Smyth, 1996);
is kept in . They are standard normal
under the model whatever the censoring. They are random: set a seed
to reproduce them; summary() draws them without changing the
caller's RNG state.
"weighted", "sweighted"
and , with
,
and (Espinheira, Ferrari and
Cribari-Neto, 2008).
Lopes (2023) also recommends the adjusted quantile residuals of Pereira (2019), which are not implemented.
Numeric vector of residuals, one per observation.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Dunn, P. K., and Smyth, G. K. (1996). Randomized quantile residuals. Journal of Computational and Graphical Statistics, 5(3), 236–244.
Espinheira, P. L., Ferrari, S. L. P., and Cribari-Neto, F. (2008). On beta regression residuals. Journal of Applied Statistics, 35(4), 407–419.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
Pereira, G. H. A. (2019). On quantile residuals in beta regression. Communications in Statistics - Simulation and Computation, 48(1), 302–316.
# Synthetic NRS-11 scores: 3 post-operative times. Simulated, not real data. set.seed(2023) nrs <- data.frame(time = factor(rep(c("6h", "12h", "24h"), each = 80), levels = c("6h", "12h", "24h"))) shp <- brs_repar(mu = plogis(-1.3 + c(0, 0.75, 0.3)[nrs$time]), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) fit <- brs(y ~ time, data = nrs, ncuts = 10) # Randomized quantile residuals: approximately N(0, 1), borders included set.seed(1) r_q <- residuals(fit, type = "rqr") qqnorm(r_q); qqline(r_q) # Midpoint-based residuals are extreme at the border scores 0 and 10 r_p <- residuals(fit, type = "pearson") tapply(r_p, cut(nrs$y, c(-1, 0, 9, 10), labels = c("0", "1-9", "10")), mean)# Synthetic NRS-11 scores: 3 post-operative times. Simulated, not real data. set.seed(2023) nrs <- data.frame(time = factor(rep(c("6h", "12h", "24h"), each = 80), levels = c("6h", "12h", "24h"))) shp <- brs_repar(mu = plogis(-1.3 + c(0, 0.75, 0.3)[nrs$time]), phi = 0.3, repar = 2) nrs$y <- round(10 * rbeta(nrow(nrs), shp$shape1, shp$shape2)) fit <- brs(y ~ time, data = nrs, ncuts = 10) # Randomized quantile residuals: approximately N(0, 1), borders included set.seed(1) r_q <- residuals(fit, type = "rqr") qqnorm(r_q); qqline(r_q) # Midpoint-based residuals are extreme at the border scores 0 and 10 r_p <- residuals(fit, type = "pearson") tapply(r_p, cut(nrs$y, c(-1, 0, 9, 10), labels = c("0", "1-9", "10")), mean)
Residuals from a brsmm model
## S3 method for class 'brsmm' residuals( object, type = c("response", "pearson", "deviance", "rqr", "weighted", "sweighted"), ... )## S3 method for class 'brsmm' residuals( object, type = c("response", "pearson", "deviance", "rqr", "weighted", "sweighted"), ... )
object |
A fitted |
type |
Character: |
... |
Currently ignored. |
Numeric vector.
brsmm, fitted.brsmm,
plot.brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(residuals(fit)) head(residuals(fit, type = "pearson"))dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) head(residuals(fit)) head(residuals(fit, type = "pearson"))
Wald tables for the mean and precision (or dispersion) coefficients,
information criteria, a pseudo , the censoring counts and a
summary of the randomized quantile residuals.
## S3 method for class 'brs' summary(object, ...)## S3 method for class 'brs' summary(object, ...)
object |
A fitted |
... |
Currently ignored. |
For each coefficient , the standard error is
from vcov.brs, the Wald
statistic is and the two-sided p-value is
(Lopes, 2023, "Inferencia"). The test is on the link
scale (). When is singular, or its inverse
has negative variances, the affected standard errors, statistics and
p-values are NA (see 'Fit diagnostics' in brs).
and ,
with the maximised log-likelihood, the number of
coefficients and the number of observations. The pseudo
is the squared correlation between the fitted linear predictor
of the mean and at the cell centres yt (Ferrari and
Cribari-Neto, 2004); under repar = 0 both sides are on the logit
scale. It uses the cell centres, so it is rough when most observations are
censored (the print says so).
The randomized quantile residuals (residuals.brs,
type = "rqr") are drawn without changing the caller's RNG state.
A list of class "summary.brs" with coefficients
(tables mean and precision with columns Estimate,
Std. Error, z value, Pr(>|z|)), residuals
(RQR), loglik, AIC, BIC, df, nobs,
pseudo.r2, censoring (counts by type), link,
link_phi, repar, convergence and iterations.
Lopes, J. E. (2023). Modelos de regressao beta para dados de escala. Master's dissertation, Universidade Federal do Parana, Curitiba. URI: https://hdl.handle.net/1884/86624.
Ferrari, S. L. P., and Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799–815. doi:10.1080/0266476042000214501
brs, confint.brs,
anova.brs, brs_gof
set.seed(2023) d <- data.frame(time = factor(rep(c("6h", "12h", "24h"), each = 60), levels = c("6h", "12h", "24h"))) shp <- brs_repar(mu = plogis(-1.3 + c(0, 0.75, 0.3)[d$time]), phi = 0.3) d$y <- round(10 * rbeta(nrow(d), shp$shape1, shp$shape2)) fit <- brs(y ~ time, data = d, ncuts = 10) s <- summary(fit) s s$coefficients$mean c(AIC = s$AIC, BIC = s$BIC, pseudo_R2 = s$pseudo.r2)set.seed(2023) d <- data.frame(time = factor(rep(c("6h", "12h", "24h"), each = 60), levels = c("6h", "12h", "24h"))) shp <- brs_repar(mu = plogis(-1.3 + c(0, 0.75, 0.3)[d$time]), phi = 0.3) d$y <- round(10 * rbeta(nrow(d), shp$shape1, shp$shape2)) fit <- brs(y ~ time, data = d, ncuts = 10) s <- summary(fit) s s$coefficients$mean c(AIC = s$AIC, BIC = s$BIC, pseudo_R2 = s$pseudo.r2)
Wald tests for the fixed effects. The random effects are reported as
standard deviations and correlations (varcorr) with Wald intervals
built on a transformed scale and mapped back: of the interval
for , of the interval for
(delta method from the packed Cholesky
parameters). No test or p-value is given for them: a z-test of
tests , and lies on the boundary;
use anova.brsmm (chi-bar-square mixture) against the model
without the term. The randomized quantile residuals are drawn without
changing the caller's RNG state.
## S3 method for class 'brsmm' summary(object, level = 0.95, ...)## S3 method for class 'brsmm' summary(object, level = 0.95, ...)
object |
A fitted |
level |
Confidence level of the |
... |
Currently ignored. |
Object of class "summary.brsmm"; coefficients$random
holds the packed Cholesky parameters (estimate and standard error only)
and varcorr the SD/correlation table.
brsmm, print.summary.brsmm,
brs_gof, brsmm_re_study
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) s <- summary(fit) s$coefficients$meandat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) s <- summary(fit) s$coefficients$mean
Variance-covariance matrix of estimated coefficients
## S3 method for class 'brs' vcov(object, model = c("full", "mean", "precision"), ...)## S3 method for class 'brs' vcov(object, model = c("full", "mean", "precision"), ...)
object |
A fitted |
model |
Character: which component ( |
... |
Ignored. |
with the Hessian of the log-likelihood at the
estimate. No generalised inverse is used: a singular Hessian gives an
NA matrix, and negative or non-finite variances become NA
(row and column); both cases warn (see fit$diagnostics).
A square numeric matrix.
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) vcov(fit) vcov(fit, model = "mean")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10) ) prep <- brs_prep(dat, ncuts = 100) fit <- brs(y ~ x1, data = prep) vcov(fit) vcov(fit, model = "mean")
Variance-covariance matrix for brsmm coefficients
## S3 method for class 'brsmm' vcov(object, model = c("full", "mean", "precision", "random"), ...)## S3 method for class 'brsmm' vcov(object, model = c("full", "mean", "precision", "random"), ...)
object |
A fitted |
model |
Character: |
... |
Currently ignored. |
Numeric matrix.
brsmm, coef.brsmm,
confint.brsmm
dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) vcov(fit, model = "mean")dat <- data.frame( y = c( 0, 5, 20, 50, 75, 90, 100, 30, 60, 45, 10, 40, 55, 70, 85, 25, 35, 65, 80, 15 ), x1 = rep(c(1, 2), 10), id = factor(rep(1:4, each = 5)) ) prep <- brs_prep(dat, ncuts = 100) fit <- brsmm(y ~ x1, random = ~ 1 | id, data = prep) vcov(fit, model = "mean")