check_asymmetry() takes an N x k binary ratings matrix and returns a
scalar delta_hat (in percentile points, "pp"): the max-min spread of
surface percentiles across the four agreement coefficients (PABAK,
AC1, Fleiss kappa, Krippendorff alpha) when each is positioned on its
calibrated reference surface. ICC is reported on the panel rows but
excluded from delta_hat (its reference is distribution-sensitive in
ways the agreement family is not).
Usage
check_asymmetry(
ratings,
axis = c("inter", "intra"),
occasion = NULL,
delta_thresholds = NULL,
...
)Arguments
- ratings
User input: an
N x kbinary matrix, anNxkdata.frame whose columns are 0/1 / logical / 2-level factor, or a list of two equal-length 0/1 vectors (k = 2 paired form). See?normalize_ratingsfor accepted shapes.- axis
"inter"(default) or"intra". Selects the surface family.- occasion
Reserved for
axis = "intra"(a vector / factor identifying viewing occasion); ignored whenaxis = "inter".- delta_thresholds
Length-2 numeric vector
c(caution, divergent)in percentile points. Defaultc(9.25, 11.75)from paper Sec.3.2 (NP optimum at alpha = 0.05 / 0.01).- ...
Forwarded to
position_on_surface()(e.g.bands,band_labels,reference_type).
Value
An S3 object of class grass_asymmetry_panel with fields:
delta_hat: scalar percentile-spread in ppflag: one of"aligned","caution","divergent"thresholds: named numeric vector of the (caution, divergent) cutoffs, in pppanel: data.frame withcoefficient,observed,percentile_ppnotes: character vector of unique caveats from the underlying surface positioning calls (e.g. nearest-neighbor gaps, ICC unavailability)
Details
delta_hat is a split-bias detector. It fires when raters tilt in
different directions across (Se, Sp) – e.g., one rater high-Se / low-Sp,
another high-Sp / low-Se – because the four coefficients respond to
heterogeneous per-rater behavior differently and end up disagreeing on
where the panel sits on the surface. The framework's other failure
mode, shared/uniform bias (every rater tilts the same direction,
e.g., a panel trained on one protocol all favoring specificity over
sensitivity), produces uniform percentile degradation across
coefficients: small delta_hat, low minimum surface percentile.
Shared bias is detected by the panel's minimum surface percentile,
not by delta_hat. A divergent flag therefore identifies a specific
kind of disagreement – cross-coefficient inversion from heterogeneous
rater behavior – and routes the user to the per-rater pairwise PABAK
matrix and pooled-reference (Se_tilde, Sp_tilde) diagnostic.
Each coefficient is positioned on its reference surface via
position_on_surface(), yielding a percentile in [0, 100] pp. The
panel diagnostic is delta_hat = max(percentile) - min(percentile),
computed over coefficients whose observed value sits within the
achievable range of their reference surface (see Surface-envelope
clamp below).
Surface-envelope clamp (v0.2.1+)
If an observed coefficient value falls outside the achievable range of
its reference surface at the study's design (pi_hat, k, N), the
inversion to q_hat clamps to the boundary and the percentile lands
at exactly 0 or 100. Including such clamped percentiles in the
max-min delta_hat would inflate the panel-spread purely because of
the clamp, not because the panel disagrees on percentile. Since
v0.2.1 the function therefore excludes clamped coefficients from
delta_hat whenever at least two unclamped coefficients remain. The
affected coefficients are still shown in the returned panel
data.frame with clamped = TRUE and surface percentile 0 or 100,
and a note in $notes names which coefficients were excluded. This
matters most often for ICC at N > 200 (the bundled fitted-ICC
reference is calibrated through N = 200; beyond that the function
falls back to the oracle reference, which over-predicts the
practitioner's GLMM-fit ICC and therefore clamps). The behavior
guarantees that a divergent flag always reflects genuine
cross-coefficient surface-percentile disagreement rather than an
envelope artifact; the trade-off is that a coefficient with no
calibrated reference at the user's design contributes nothing to
the diagnostic. If fewer than two unclamped coefficients remain,
delta_hat falls back to the raw spread including clamped values
and the note records the fallback.
Tier thresholds default to c(9.25, 11.75) pp, the Neyman-Pearson-motivated
size-alpha cutoffs at alpha = 0.05 and alpha = 0.01 from Sec.3.2 of the
GRASS paper (see also App G operating characteristics). The construction is
NP-optimal within the test class of threshold rules on delta_hat; it is
not a likelihood-ratio test on the joint distribution of the panel
coefficients (delta_hat is a paired-margin difference, not a likelihood
ratio). The three flags are:
aligned(delta_hat < 9.25pp): the panel agrees on the surface position. Any single coefficient is a stable summary; the primary coefficient (Table 2) carries the headline.caution(9.25 <= delta_hat < 11.75pp): the panel is mildly inconsistent. Report the primary coefficient with a caution flag and thedelta_hatvalue.divergent(delta_hat >= 11.75pp): no single coefficient is a stable summary. Uselatent_class_fit()to recover per-rater(Se, Sp)and report those instead.
The new check_asymmetry(ratings, ...) signature replaces the
v0.1.x check_asymmetry(se, sp, ...) per-rater signature. For
backward compatibility, calling check_asymmetry() with se = ...
and sp = ... named arguments emits a one-time deprecation hint and
routes the call to check_rater_asymmetry(). Supplying both
ratings = ... and per-rater se = / sp = is an error.
References
Neyman, J. and Pearson, E. S. (1933). On the problem of the most efficient tests of statistical hypotheses. Philosophical Transactions of the Royal Society of London A, 231, 289-337.
See also
check_rater_asymmetry() for the per-rater Se/Sp companion;
latent_class_fit() for the divergent-branch recovery of per-rater
(Se, Sp); position_on_surface() for the underlying surface
positioning.
Examples
# \donttest{
set.seed(1)
# Build a 5x200 symmetric panel -- should print as 'aligned'.
Y <- matrix(rbinom(5 * 200, 1, 0.30), nrow = 200, ncol = 5)
check_asymmetry(Y)
#> GRASS panel asymmetry diagnostic
#>
#> delta_hat = 3.1 pp
#> flag = aligned (< 9.2)
#>
#> panel:
#> coefficient observed percentile (pp) in delta_hat
#> pabak 0.16 47.5 yes
#> mean_ac1 0.27 46.2 yes
#> fleiss_kappa 0.00 49.3 yes
#> icc 0.00 0.0 no [distribution-sensitive]
#>
#> Surface caveats:
#> - Fitted-ICC F_key picked via glmer: mu_hat=-0.831, tau2_hat=0.011 -> F_key tau2=0.0625, mu=-0.847.
#> - Fitted-ICC reference (GLMM-gap corrected) at F_key=LN_mu=-0.847_tau2=0.0625, k=5, N=200 (family=logit_normal, M1=0.303).
#> - obs_value 0.0034 below achievable minimum (0.0834); q_hat clamped.
#> - Delta-method SE undefined: dE/dq near zero at q_hat.
#> - delta_hat is computed over the agreement family (PABAK, AC1, Fleiss, alpha). ICC is reported on the panel but does not enter delta_hat (v0.5.0 scope: ICC's reference surface depends on the full subject-prevalence distribution F and does not share the (q, pi_+) sufficient statistic the agreement family does).
# }