Skip to contents

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 k binary matrix, an N x k data.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_ratings for 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 uses occasion to identify viewings.

metric

One of "auto" (default; calls pick_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. Use obs_krippendorff_alpha() or position_on_surface() to compute it manually.)

occasion

Reserved for axis = "intra"; ignored when axis = "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. Default 0L (off); values below 50L are 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:

  1. Normalize ratings to a canonical N x k integer matrix Y and derive pi_hat = mean(Y), k = ncol(Y), N = nrow(Y). Validate k >= 2; warn at N < 10; note at N < 30.

  2. Compute the panel of observed coefficients (compute_panel(), internal): at k = 2, PABAK / AC1 / Cohen's kappa; at k >= 3, PABAK / AC1 / Fleiss kappa / ICC.

  3. For each panel coefficient, position the observed value on its DGP-calibrated reference surface via position_on_surface().

  4. Pick the primary coefficient via Table 2 (metric = "auto") or accept the user's override.

  5. Compute the cross-coefficient implied-quality spread delta_hat (in pp of quality) via check_asymmetry() and flag aligned / caution / divergent by delta_hat's percentile on the matched (k, N, q_hat) null.

  6. If flag == "divergent": run a latent_class_fit() (Dawid-Skene EM at k >= 3; Hui-Walter bounds at k = 2) and attach the per-rater (Se_j, Sp_j) table.

  7. Assemble the grass_card S3 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