Learn R Programming

matrixCorr (version 0.12.3)

prob_agree: Probability of Agreement for Reliability Curves

Description

prob_agree() implements the probability of agreement following Stevens and Anderson-Cook (2017). It fits binomial reliability curves by population or generation and estimates, for each pair, the probability that the fitted reliabilities differ by no more than a user-specified practically negligible amount.

This is not a correlation coefficient and should not be interpreted as linear association. It is a tolerance-based agreement measure. It is computed from the sampling distribution of the estimated difference between two reliability curves.

Usage

prob_agree(
  data,
  response,
  predictor,
  group,
  delta = NULL,
  limits = NULL,
  link = c("logit", "probit"),
  newdata = NULL,
  grid_size = 100L,
  ci = TRUE,
  conf_level = 0.95,
  max_iter = 50L,
  tol = 1e-08,
  verbose = FALSE
)

Value

A data frame with class c("prob_agree_curve", "prob_agree", "data.frame") and columns group1, group2, the predictor, prob_agree, and optional lwr.ci, upr.ci.

Arguments

data

A data frame containing the response, predictor, and group variables.

response

Character scalar naming the binary pass/fail response column.

predictor

Character scalar naming the numeric age, time, or operating condition column.

group

Character scalar naming the population/generation column. All pairwise comparisons among the observed non-missing levels are evaluated.

delta

Positive scalar or vector tolerance for symmetric limits -delta and delta. A length-two vector with a negative lower bound and a positive upper bound, for example c(-0.03, 0.05), is treated as an asymmetric tolerance interval. No default is provided because the tolerance is part of the scientific estimand.

limits

Numeric vector c(lower, upper) for asymmetric tolerance limits. Mutually exclusive with delta.

link

Link used for the reliability curve: "logit" or "probit".

newdata

Optional data frame containing predictor values where the probability of agreement is evaluated. If NULL, a regular grid over the observed predictor range is used.

grid_size

Integer number of evaluation points when newdata = NULL.

ci

Logical; if TRUE, attach pointwise confidence limits.

conf_level

Confidence level for intervals.

max_iter

Maximum number of IRLS iterations for each fitted curve.

tol

Convergence tolerance for IRLS coefficient updates.

verbose

Logical; if TRUE, emits a short cli message.

Author

Thiago de Paula Oliveira

Details

For each pair of fitted reliability curves \(\hat\pi_1(a)\) and \(\hat\pi_2(a)\), Stevens and Anderson-Cook define $$\theta(a) = P\{|\tilde\pi_1(a) - \tilde\pi_2(a)| \le \delta(a) \mid a\}.$$ The models are fit with a binomial GLM using either a logit or probit link, with \(g(\pi_i) = \beta_0 + \beta_1 a_i\). The C++ backend evaluates the two-population large-sample normal approximation described in the paper and Supplementary Material A; when more than two groups are supplied, prob_agree() applies that calculation to all pairwise group comparisons.

Missing rows in response, predictor, or group are removed before model fitting. The response must be binary, coded as 0/1, FALSE/TRUE, or a two-level factor.

References

Stevens, N. T. and Anderson-Cook, C. M. (2017). Comparing the Reliability of Related Populations With the Probability of Agreement. Technometrics, 59(3), 371-380. doi:10.1080/00401706.2016.1214180.

Examples

Run this code
# Stevens and Anderson-Cook's probability of agreement evaluates whether
# two related populations have reliability curves that are similar enough
# to be treated as practically homogeneous. At each age, the agreement
# hypothesis is that the difference between the two fitted reliabilities
# lies inside the user-specified practical tolerance interval.
set.seed(1)
n <- 160
dat <- data.frame(
  age = c(runif(n, 0, 60), runif(n, 0, 45)),
  generation = rep(c("Gen1", "Gen2"), each = n)
)
eta <- ifelse(
  dat$generation == "Gen1",
  4.3 - 0.045 * dat$age,
  4.0 - 0.040 * dat$age
)
dat$pass <- rbinom(nrow(dat), size = 1, prob = plogis(eta))

fit_pa <- prob_agree(
  dat,
  response = "pass",
  predictor = "age",
  group = "generation",
  delta = 0.05,
  link = "logit",
  ci = TRUE
)
print(fit_pa)
summary(fit_pa)
estimate(fit_pa)
tidy(fit_pa)
confint(fit_pa)
plot(fit_pa)

# Four generations are compared as all pairwise two-generation contrasts.
set.seed(2)
n4 <- 120
dat4 <- data.frame(
  age = rep(runif(n4, 0, 55), times = 4),
  generation = rep(paste0("Gen", 1:4), each = n4)
)
shifts <- c(4.2, 4.0, 3.8, 3.6)
slopes <- c(-0.040, -0.042, -0.044, -0.046)
gen_id <- match(dat4$generation, paste0("Gen", 1:4))
eta4 <- shifts[gen_id] + slopes[gen_id] * dat4$age
dat4$pass <- rbinom(nrow(dat4), size = 1, prob = plogis(eta4))

fit4 <- prob_agree(
  dat4,
  response = "pass",
  predictor = "age",
  group = "generation",
  limits = c(-0.03, 0.05),
  link = "logit",
  ci = FALSE
)
print(fit4)
plot(fit4)

Run the code above in your browser using DataLab