grass_report() is the headline entry point for the v0.2.0 Target-2
framework. It takes an N x k binary rating matrix and returns a
four-field Report Card: the sample summary (k, N, pi_hat), the primary
coefficient and its surface position, the cross-coefficient asymmetry
diagnostic delta_hat and flag, and (when flag == "divergent") the
per-rater latent-class fit. The full panel of coefficients, pooled
percentiles, consistency bands on quality, and reference-surface
artifacts ride along on the same object for summary(),
as.data.frame(), and plot() access.
Usage
grass_report(
ratings,
axis = c("inter", "intra"),
metric = "auto",
occasion = NULL,
bootstrap_B = 1000L,
bootstrap_delta_B = 0L,
verbose = FALSE,
...
)Arguments
- ratings
User input: an
N x kbinary matrix, anN x kdata.frame whose columns are 0/1 / logical / 2-level factor, or a list of two equal-length 0/1 vectors (k = 2paired form). See?normalize_ratingsfor accepted shapes. Rows must be independent subjects, one row each: the calibration assumes every row is a new subject, and stacking repeated measurements of one subject as rows overstates the effective sample size (analyze one card per occasion instead;vignette("grassr"), section "The data").- axis
One of
"inter"(default) or"intra". Selects the surface family. The intra-axis path usesoccasionto identify viewings.- metric
One of
"auto"(default; callspick_primary_coefficient()per Table 2),"pabak","ac1","fleiss_kappa","icc". Selects which coefficient is the headline in the printed Report Card; the full panel is always populated. (Krippendorff's alpha left the Report Card panel at v0.6.0; it coincides with Fleiss' kappa in the binary fully-crossed case. Useobs_krippendorff_alpha()orposition_on_surface()to compute it manually.)- occasion
Reserved for
axis = "intra"; ignored whenaxis = "inter".- bootstrap_B
Integer; bootstrap replicates for the divergent-branch latent-class CIs. Default
1000L. Set lower for fast tests.- bootstrap_delta_B
Integer; subject-resampling replicates for the optional bootstrap distribution of
delta_hat. Default0L(off); values below50Lare treated as off.- verbose
Logical; emit progress messages on long calls. Default
FALSE.- ...
Reserved for future extension.
Value
An object of class c("grass_card", "list") with fields
sample, coefficient, delta, panel, per_rater, surface,
call, grass_version, timestamp, inputs, notes. See the
v0.2.0 paper-alignment design doc Sec.3.1 for the full structure.
coefficient carries the primary coefficient's observed_value,
its surface_percentile (the pooled percentile – position within the
design's achievable agreement range – on the 0-100 scale), the
implied panel quality q_hat, and the 95% test-inversion
consistency_band on quality (suppressed at the divergent flag).
panel is a data.frame with one row per coefficient carrying its
observed_value, surface_percentile, consistency-band columns
(band_lo, band_hi, band_open_low, band_open_high), q_hat,
se_q_hat, clamped, reference_used, and in_delta_hat.
delta carries delta_hat (implied-quality spread, in pp of
quality), delta_percentile (its percentile on the matched null),
flag, matched_null, thresholds, and thresholds_source.
Percentile units. card$coefficient$surface_percentile and
card$panel$surface_percentile are reported on the 0-100 scale
(e.g., 46.3 means the 46th percentile). The underlying
position_on_surface() returns percentile on the 0-1 fraction
scale; grass_report() multiplies by 100 to match the paper's
prose convention. The print and format methods use ordinal
notation ("46th percentile").
Details
The body, in order:
Normalize
ratingsto a canonicalN x kinteger matrixYand derivepi_hat = mean(Y),k = ncol(Y),N = nrow(Y). Validatek >= 2; warn atN < 10; note atN < 30.Compute the panel of observed coefficients (
compute_panel(), internal): atk = 2, PABAK / AC1 / Cohen's kappa; atk >= 3, PABAK / AC1 / Fleiss kappa / ICC.For each panel coefficient, position the observed value on its DGP-calibrated reference surface via
position_on_surface().Pick the primary coefficient via Table 2 (
metric = "auto") or accept the user's override.Compute the cross-coefficient implied-quality spread
delta_hat(in pp of quality) viacheck_asymmetry()and flagaligned/caution/divergentbydelta_hat's percentile on the matched (k, N, q_hat) null.If
flag == "divergent": run alatent_class_fit()(Dawid-Skene EM atk >= 3; Hui-Walter bounds atk = 2) and attach the per-rater(Se_j, Sp_j)table.Assemble the
grass_cardS3 object.
Examples
# k >= 3 computes ICC via a glmer fit when lme4 (Suggests) is
# available; without lme4 the card degrades gracefully to the
# agreement family.
set.seed(1)
Y <- matrix(rbinom(1000, 1, 0.3), nrow = 200, ncol = 5)
card <- grass_report(ratings = Y)
card # print
#> GRASS Report Card
#>
#> sample = 5 raters, N = 200, pi_hat = 0.30
#> PABAK = 0.16 -> 34th percentile | quality 0.65-0.75 <- primary
#> AC1 = 0.27 -> 34th percentile | quality 0.65-0.75
#> Fleiss kappa = 0.00 -> 34th percentile | quality 0.65-0.75
#> ICC = 0.00 -> 0th percentile | quality <= 0.55 [distribution-sensitive]
#> read: this panel agreed more tightly than 34% of what panels at this design can produce; the data are consistent with panel quality 0.65-0.75.
#> delta = 0 pp implied-quality spread (aligned)
#> matched null = (k=5, N=200, q=0.70): delta_hat at the 0.5 percentile [design snapped]
#>
#> Notes:
#> - obs_value 0.0034 below achievable minimum (0.0834); q_hat clamped.
#> - Delta-method SE undefined: dE/dq near zero at q_hat.
#> - Observed value below the sampling range of the lowest calibrated quality (q = 0.55); consistency band open below the calibrated grid.
#> - delta_hat is the implied-quality spread over the agreement family (PABAK, mean AC1, Fleiss kappa). ICC is reported on the panel but does not enter delta_hat (v0.5.0 scope: ICC's reference depends on the full subject-prevalence distribution F and does not share the (q, pi_+) sufficient statistic the agreement family does).
#> - flag from delta_hat's percentile on the matched null (k=5, N=200, q=0.70, prev=0.05; 50,000 draws); design snapped to the calibrated grid; null interpolated between calibrated grid nodes.
#>
#> See `summary(...)` for full panel and CI details.
#> See `plot(...)` for a surface-position visualization.
summary(card) # full panel + per-rater
#> GRASS Report Card -- summary
#>
#> sample : k = 5 raters, N = 200, pi_hat = 0.304, axis = inter
#> tau2_hat : 0.001
#>
#> primary coefficient
#> name : pabak
#> observed : 0.156
#> percentile : 33.69 pp (pooled; position in the design's achievable range)
#> q_hat : 0.697
#> band : consistent with panel quality 0.65-0.75 (95%)
#> basis : pooled-achievable-range
#>
#> delta (cross-coefficient asymmetry)
#> implied-q spread (pp) : 0.00
#> flag : aligned
#> delta percentile : 0.5 pctile on matched null (k=5, N=200, q=0.70)
#>
#> panel (full table)
#> pabak observed = 0.156 q_hat = 0.697 pct = 33.69 pp quality 0.65-0.75 ref = closed-form
#> mean_ac1 observed = 0.268 q_hat = 0.697 pct = 33.65 pp quality 0.65-0.75 ref = closed-form
#> fleiss_kappa observed = 0.003 q_hat = 0.697 pct = 33.80 pp quality 0.65-0.75 ref = closed-form
#> icc observed = 0.003 q_hat = 0.500 pct = 0.00 pp quality <= 0.55 ref = fitted-icc
#>
#> notes
#> - 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.
#> - Observed value below the sampling range of the lowest calibrated quality (q = 0.55); consistency band open below the calibrated grid.
#> - delta_hat is the implied-quality spread over the agreement family (PABAK, mean AC1, Fleiss kappa). ICC is reported on the panel but does not enter delta_hat (v0.5.0 scope: ICC's reference depends on the full subject-prevalence distribution F and does not share the (q, pi_+) sufficient statistic the agreement family does).
#> - flag from delta_hat's percentile on the matched null (k=5, N=200, q=0.70, prev=0.05; 50,000 draws); design snapped to the calibrated grid; null interpolated between calibrated grid nodes.
#>
#> grass version : 0.8.0
#> timestamp : 2026-08-29 23:18:12
as.data.frame(card) # tidy long-format
#> coefficient observed_value surface_percentile band_lo band_hi
#> 1 pabak 0.156000000 3.369383e+01 0.6514539 0.7473689
#> 2 mean_ac1 0.268413610 3.365363e+01 0.6523213 0.7472916
#> 3 fleiss_kappa 0.002760133 3.379680e+01 0.6506700 0.7474623
#> 4 icc 0.003421860 5.040648e-04 NA 0.5500000
#> band_open_low band_open_high q_hat se_q_hat clamped reference_used
#> 1 FALSE FALSE 0.6974835 0.02439619 FALSE closed-form
#> 2 FALSE FALSE 0.6974805 0.02439621 FALSE closed-form
#> 3 FALSE FALSE 0.6974835 0.02439619 FALSE closed-form
#> 4 TRUE FALSE 0.5000000 NA TRUE fitted-icc
#> in_delta_hat is_primary delta_hat delta_percentile delta_flag
#> 1 TRUE TRUE 0.0003089194 0.5 aligned
#> 2 TRUE FALSE 0.0003089194 0.5 aligned
#> 3 TRUE FALSE 0.0003089194 0.5 aligned
#> 4 FALSE FALSE 0.0003089194 0.5 aligned
#> matched_null_k matched_null_N matched_null_q
#> 1 5 200 0.6974835
#> 2 5 200 0.6974835
#> 3 5 200 0.6974835
#> 4 5 200 0.6974835