GRASS methods companion: notation, calibration detail, and auxiliary diagnostics
Austin Semmel
Rachel Gidaro
2026-07-03
Source:vignettes/methods-companion.Rmd
methods-companion.RmdScope of this companion
This vignette accompanies the GRASS methods paper. It is a parallel
reference: the paper is self-contained for review, while this companion
carries the procedural detail and auxiliary diagnostics a practitioner
running grassr may want at hand. Section numbering does not
parallel the paper.
Content moved here from earlier paper appendices during the
2026-05-04 appendix consolidation. The paper does not cite this
vignette; this is a free-standing artifact for
grassr users.
1. Notation glossary
Symbols used throughout the package and the paper:
-
Y— the binary rating matrix; rows are subjects, columns are raters. -
pi_hat— observed marginal positive rate. -
tau2_hat— between-subject variance of the per-subject mean call rate (sample-side, computed fromY). -
Se_j,Sp_j— per-rater sensitivity and specificity, inferred from the rating matrix, not against external truth. -
q— diagonal-DGP rater quality; for every rater under the diagonal case the surfaces are calibrated on. -
q_hat— internal scaffolding only. Used byposition_on_surface()to select the sampling distribution from which the percentile is read; not exposed on the Report Card. -
delta_hat— cross-coefficient surface-percentile spread.
2. Recovering from an observed coefficient
For each agreement coefficient, position_on_surface()
inverts the closed-form expectation curve to recover
at the observed coefficient value.
- PABAK: algebraic inverse, .
- Fleiss , Krippendorff , AC1, ICC: 501-point -grid lookup with linear interpolation between the two nearest grid points where the curve crosses the observed value.
-
Out-of-range observations: clamped to the boundary
value with a
clamped = TRUEflag.
3. ICC and the subject-prevalence distribution
The Report Card prints ICC alongside PABAK, AC1, and Fleiss
,
but with a [distribution-sensitive] marker, and ICC is
excluded from the cross-coefficient stability signal
by construction.
The agreement-family coefficients each have a closed-form expectation that depends only on the panel marginal and the rater quality . ICC depends additionally on the full distribution of subject-level positive probabilities across the rated subjects — the shape of how the underlying positive rate varies from one subject to the next. Two studies can both have an overall positive rate of 30% and yet differ on whether that 30% comes from a clear class of obvious-positives (high between-subject variance) or from a mass of borderline-50/50 cases (low between-subject variance). The agreement-family coefficients can’t tell those two studies apart at the panel level. ICC can, and so its reference surface must commit to a specific .
The bundled grassr reference covers a 48-point
logit-normal grid in
plus four discrete-mixture profiles (uniform, bimodal-low-high,
skew-rare-positive, and similar shapes). A panel whose true
sits cleanly inside that grid reads ICC’s surface percentile faithfully.
A panel whose
sits between grid points or under a different family carries a
distribution-mismatch cost that the agreement-family percentiles do not.
This is why ICC carries a [distribution-sensitive] marker
on the Report Card and does not enter
.
Variant selection (ICC(1,1), ICC(2,1), ICC(3,1))
follows the Koo and Li (2016) decision tree on both the inter-rater and
intra-rater axes. The package exposes each variant through the
metric argument of position_on_surface(). The
four-question decision tree (same-rater-set / rater sampling / type /
definition) is reproduced with worked examples per branch in the package
help files.
4. Coefficient recovery: the full diagnostic
The paper’s App C carries the lead recovery table plus the asymmetry-cost figures. This companion expands the same dataset across the full grid.
5. thresholds and operating characteristics
The paper’s Appendix~D carries the per- calibrated threshold table, the adopted-thresholds at the modal applied design, the TPR-by-asymmetry-magnitude tables for both caution and divergent flags, and the shared-bias vs split-bias detection comparison. This section populates the practitioner-facing detail that didn’t make the paper.
How the thresholds are derived. At each design point, the cuts are size- calibrated against the diagonal-symmetric null distribution of following the Neyman-Pearson construction: pick the smallest such that on the calibration grid, with for caution and for divergent. The thresholds are therefore a function of , not a fixed pair. At the modal applied design (, ) the cuts are pp; at smaller designs they shift upward (the snapped pair at , is pp).
Small-design behavior. At and at with , the diagonal-null distribution of has heavy tails that no size- cut controls. The lookup snaps such panels to the nearest fully-calibrated cell on the grid and surfaces the snap on the Report Card; this is an optimistic lower bound rather than a calibrated cut at the user’s design. At the snap collapses to at the same , because the panel-level coefficient battery at (PABAK, AC1, Cohen’s ) measures effectively the same agreement structure under both the symmetric null and the asymmetric alternatives. This is why the framework’s prescription routes to direct pairwise reporting and identifiable bounds on per-rater $(\Se_j, \Sp_j)$ rather than relying on to fire.
What targets. targets cross-coefficient surface-percentile inversion — the asymmetry pattern in which different chance-correction baselines respond differently to per-rater heterogeneity. Independently-drawn-sign asymmetry produces this inversion; uniform shared bias, conditional dependence, and other panel pathologies that move all coefficients together do not. Paper Appendix~D documents the gap: at the divergent flag’s TPR plateaus near – under split-bias asymmetry, while shared-bias panels move all three coefficients together and leave nearly unmoved; the percentile, not , carries the shared-bias signal.
5b. Pairwise PABAK and pooled-reference recovery
When the divergent flag fires, the Report Card abandons the panel-aggregate summary and routes to a pairwise PABAK matrix plus per-rater pooled-reference $(\widetilde\Se_j, \widetilde\Sp_j)$.
Why PABAK at the pair level. PABAK is the framework’s pairwise coefficient because under symmetric raters its closed-form expectation reduces to , a function of rater quality alone — independent of prevalence and of the subject-prevalence distribution . Pairwise reading needs that property because every rater pair has its own observed marginal , and those per-pair marginals can move substantially with rater asymmetry. Cohen’s at the pair level is prevalence-attenuated (the paradox of Byrt, Bishop, and Carlin (1993), the original motivation for PABAK); AC1’s chance term carries a milder but non-zero prevalence dependence; ICC at is degenerate because one pair of raters per subject leaves the variance decomposition under-identified.
Pooled-reference identifiability. The pooled-reference estimates are label-flip clean conditional on the panel-majority direction matching the truth direction: the reference is the observable panel majority rather than a latent class, so the estimates do not depend on which mode an EM solver lands in. They read each rater’s profile relative to whichever direction dominates the panel. Under a 2:3 panel where the minority direction happens to be the truth direction, the pooled-reference inverts and reads each rater’s profile backwards.
Empirical recovery (54-cell Monte Carlo). A sweep over , , asymmetry magnitude , and both shared-bias and split-bias configurations at with replications per cell:
- Pooled-reference recovers each rater’s true bias direction in of split-bias in-majority-direction rater-replicates (rate improving in from at to at ).
- Correctly inverts the direction in of minority-direction rater-replicates — exactly as the conditional predicts.
- Mean bias on $\widetilde\Se_j$ is and on $\widetilde\Sp_j$ is at .
The pooled-reference summary is meaningful only at (no rest-of-panel to pool against at ) and is noisier on subjects where the panel is split. The package reports the per-rater pool size alongside each pooled estimate so the reader can see how much information backs each one.
6. Worked code examples per Report Card branch
A small helper generates an N x k rating matrix under
the paper’s diagonal DGP at a stated seed, k,
N, per-rater Se/Sp, target
prevalence pi, and logit-normal spread parameter
F_sigma2:
library(grassr)
simulate_panel <- function(seed, k, N, Se, Sp, pi, F_sigma2 = 0.25) {
stopifnot(length(Se) == k, length(Sp) == k)
set.seed(seed)
mu_logit <- qlogis(pi)
p_i <- plogis(rnorm(N, mu_logit, sqrt(F_sigma2)))
C <- rbinom(N, 1L, p_i)
Y <- matrix(0L, N, k)
for (j in seq_len(k)) {
Y[, j] <- rbinom(N, 1L, ifelse(C == 1L, Se[j], 1 - Sp[j]))
}
Y
}Aligned case (paper §4.1)
# Se = Sp = 0.85, k = 5, N = 1000, seed = 5
Y_aligned <- simulate_panel(
seed = 5L, k = 5L, N = 1000L,
Se = rep(0.85, 5), Sp = rep(0.85, 5),
pi = 0.08
)
card_aligned <- grass_report(Y_aligned)
card_aligned
#> GRASS Report Card
#>
#> sample = 5 raters, N = 1000, pi_hat = 0.21
#> PABAK = 0.49 -> 46th percentile (decisive) <- primary
#> AC1 = 0.62 -> 46th percentile
#> Fleiss kappa = 0.23 -> 47th percentile
#> ICC = 0.33 -> 50th percentile [distribution-sensitive]
#> delta = 1 pp (aligned)
#> thresholds = (8.50, 9.75) [calibrated at nearest grid cell (snapped)]
#>
#> Notes:
#> - (k = 5, N = 1000) has no fully-calibrated threshold pair on the grid (or is off-grid); using nearest fully-calibrated cell (k = 5, N = 500).
#> - Fitted-ICC F_key picked via glmer: mu_hat=-1.716, tau2_hat=1.633 -> F_key tau2=1.0000, mu=-1.386.
#> - Fitted-ICC reference (GLMM-gap corrected) at F_key=LN_mu=-1.386_tau2=1.0000, k=5, N=1000 (family=logit_normal, M1=0.239).
#>
#> See `summary(...)` for full panel and CI details.
#> See `plot(...)` for a surface-position visualization.The three agreement coefficients land within ~1 pp of each other on
their reference surfaces; the panel is aligned and the primary
coefficient (PABAK) is safe to cite. ICC is reported alongside with
[distribution-sensitive] since its reference surface
depends on the full subject-prevalence distribution rather than on
(q, pi_hat) alone.
Divergent case (paper §4.2)
# op_strong panel: R1,R3,R5 at Se=0.95/Sp=0.75; R2,R4 inverted
# k = 5, N = 1000, seed = 6, balanced prevalence
Y_divergent <- simulate_panel(
seed = 6L, k = 5L, N = 1000L,
Se = c(0.95, 0.75, 0.95, 0.75, 0.95),
Sp = c(0.75, 0.95, 0.75, 0.95, 0.75),
pi = 0.50
)
card_divergent <- grass_report(Y_divergent)
card_divergent
#> GRASS Report Card
#>
#> sample = 5 raters, N = 1000, pi_hat = 0.50
#> PABAK = 0.49 -> 40th percentile <- primary
#> AC1 = 0.49 -> 58th percentile
#> Fleiss kappa = 0.49 -> 41st percentile
#> ICC = 0.62 -> 50th percentile [distribution-sensitive]
#> panel-agg. = suppressed (divergent)
#> delta = 18 pp (divergent)
#> thresholds = (8.50, 9.75) [calibrated at nearest grid cell (snapped)]
#>
#> pairwise PABAK / surface percentile (lower / upper):
#> R1 R2 R3 R4 R5
#> R1 -- 25% 79% 43% 98%
#> R2 0.47 -- 97% 90% 17%
#> R3 0.51 0.41 -- 98% 96%
#> R4 0.48 0.52 0.42 -- 62%
#> R5 0.55 0.46 0.54 0.50 --
#>
#> per-rater vs panel-majority of OTHER raters (pooled-reference):
#> R1 Se_tilde = 0.94 Sp_tilde = 0.77 (n_pos = 434, n_neg = 471, excl = 95)
#> R2 Se_tilde = 0.71 Sp_tilde = 0.95 (n_pos = 466, n_neg = 439, excl = 95)
#> R3 Se_tilde = 0.95 Sp_tilde = 0.71 (n_pos = 433, n_neg = 485, excl = 82)
#> R4 Se_tilde = 0.74 Sp_tilde = 0.95 (n_pos = 468, n_neg = 441, excl = 91)
#> R5 Se_tilde = 0.96 Sp_tilde = 0.78 (n_pos = 428, n_neg = 476, excl = 96)
#>
#> per-rater (latent-class fit; alongside pairwise):
#> R1 Se = 0.95 (0.21, 0.97) Sp = 0.78 (0.05, 0.82)
#> R2 Se = 0.73 (0.05, 0.77) Sp = 0.95 (0.27, 0.97)
#> R3 Se = 0.96 (0.27, 0.98) Sp = 0.72 (0.04, 0.76)
#> R4 Se = 0.75 (0.05, 0.79) Sp = 0.95 (0.25, 0.97)
#> R5 Se = 0.96 (0.22, 0.98) Sp = 0.78 (0.04, 0.82)
#>
#> Notes:
#> - (k = 5, N = 1000) has no fully-calibrated threshold pair on the grid (or is off-grid); using nearest fully-calibrated cell (k = 5, N = 500).
#> - Fitted-ICC F_key picked via glmer: mu_hat=0.005, tau2_hat=5.278 -> F_key tau2=4.0000, mu=0.000.
#> - Fitted-ICC reference (GLMM-gap corrected) at F_key=LN_mu=+0.000_tau2=4.0000, k=5, N=1000 (family=logit_normal, M1=0.500).
#>
#> See `summary(...)` for full panel and CI details.
#> See `plot(...)` for a surface-position visualization.All three agreement coefficients return values around 0.49 (uniformly
moderate by Landis-Koch) but the surface percentiles spread by
~18 pp: AC1 lands materially higher than the κ-family. The
divergent flag fires; the panel-aggregate summary is
suppressed; the Report Card emits the pairwise PABAK matrix and
per-rater pooled-reference (Se_tilde, Sp_tilde) against the
panel-majority of the other k - 1 raters.
counterexample (paper §4.3)
# High-quality k = 2 panel: Se = Sp = 0.97, pi = 0.08, N = 200
Y_k2 <- simulate_panel(
seed = 17L, k = 2L, N = 200L,
Se = rep(0.97, 2), Sp = rep(0.97, 2),
pi = 0.08
)
card_k2 <- grass_report(Y_k2)
card_k2
#> GRASS Report Card
#>
#> sample = 2 raters, N = 200, pi_hat = 0.11
#> PABAK = 0.89 -> 50th percentile
#> AC1 = 0.93 -> 55th percentile (decisive) <- primary
#> delta = 5.4 pp (aligned)
#> thresholds = (8.25, 9.75) [calibrated at nearest grid cell (snapped)]
#>
#> Notes:
#> - (k = 2, N = 200) has no fully-calibrated threshold pair on the grid (or is off-grid); using nearest fully-calibrated cell (k = 3, N = 200).
#>
#> See `summary(...)` for full panel and CI details.
#> See `plot(...)` for a surface-position visualization.Single-pair high-quality panel; the bundled k = 2 surface (densified
to 12 q-points in v0.5.2) places the panel near the median of its
(k, N, pi_hat) reference cohort.
7. Audit pass-rate detail
The paper’s App B (Reproducibility, grids, and DGPs) summarizes audit pass rates at Bonferroni-corrected . This companion lists the per-cell audit results for reviewers wanting to verify any specific corner.
8. Confidence-interval methods detail
The paper App B carries the load-bearing CI numbers (Monte-Carlo error on percentile, nearest-neighbour cost, bootstrap coverage at one calibration point). This companion adds the implementation detail.
References
The paper’s bibliography is the authoritative source. Key methodological references this companion leans on:
- Byrt, Bishop, Carlin (1993) — PABAK derivation.
- Cohen (1960), Fleiss (1971) — family.
- Gwet (2008) — AC1.
- Krippendorff (2011, 2019) — .
- Koo & Li (2016) — ICC variant selection.
- Hui & Walter (1980) — identifiability bounds.
- Dawid & Skene (1979) — latent-class fit.
- Neyman & Pearson (1933) — size-controlled testing.
(Full citations in references.bib next to the paper
source.)