Skip to contents

Build a category structure report (preferred alias)

Usage

category_structure_report(
  fit,
  diagnostics = NULL,
  theta_range = c(-6, 6),
  theta_points = 241,
  drop_unused = FALSE,
  include_fixed = FALSE,
  fixed_max_rows = 200
)

Arguments

fit

Output from fit_mfrm().

diagnostics

Optional output from diagnose_mfrm().

theta_range

Theta/logit range used to derive transition points.

theta_points

Number of grid points used for transition-point search.

drop_unused

If TRUE, remove zero-count categories from outputs.

include_fixed

If TRUE, include a legacy-compatible fixed-width text block.

fixed_max_rows

Maximum rows per fixed-width section.

Value

A named list with category-structure components. Class: mfrm_category_structure.

Details

Preferred high-level API for category-structure diagnostics. This wraps the legacy-compatible bar/transition export and returns a stable bundle interface for reporting and plotting.

Interpreting output

Key components include:

  • category usage/fit table (count, expected, infit/outfit, ZSTD)

  • threshold ordering and adjacent threshold gaps

  • category transition-point table on the requested theta grid

Practical read order:

  1. summary(out) for compact warnings and threshold ordering.

  2. out$category_table for sparse/misfitting categories.

  3. out$transition_points to inspect crossing structure.

  4. plot(out) for quick visual check.

Typical workflow

  1. fit_mfrm() -> model.

  2. diagnose_mfrm() -> residual/fit diagnostics (optional argument here).

  3. category_structure_report() -> category health snapshot.

  4. summary() and plot() for draft-oriented review of category structure.

Examples

toy <- load_mfrmr_data("example_core")
fit <- fit_mfrm(toy, "Person", c("Rater", "Criterion"), "Score", method = "JML", maxit = 25)
out <- category_structure_report(fit)
summary(out)
#> mfrmr Category Structure Summary 
#>   Class: mfrm_category_structure
#>   Components (6): category_table, mode_peaks, mode_boundaries, median_thresholds, mean_halfscore_points, settings
#> 
#> Category structure overview
#>  Categories UsedCategories FlaggedStats ModeBoundaries MeanHalfscorePoints
#>           4              4            8              3                   3
#> 
#> Category structure rows: category_table
#>  Category Count AvgPersonMeasure ExpectedAverage Infit Outfit MeanResidual
#>         1   139           -0.985           1.864 1.807  1.602       -0.864
#>         2   241           -0.376           2.262 0.614  0.781       -0.262
#>         3   252            0.328           2.734 0.556  0.618        0.266
#>         4   136            1.069           3.145 1.871  1.590        0.855
#>  DF_Infit DF_Outfit Percent InfitZSTD OutfitZSTD ExpectedCount ExpectedPercent
#>    70.923       139  18.099     3.949      4.294       139.007            18.1
#>   137.987       241  18.099    -3.702     -2.574       240.946            18.1
#>   145.246       252  18.099    -4.505     -4.968       252.005            18.1
#>    66.709       136  18.099     4.081      4.175       136.042            18.1
#>  DiffCount DiffPercent LowCount InfitFlag OutfitFlag ZSTDFlag
#>     -0.007      -0.001    FALSE      TRUE       TRUE     TRUE
#>      0.054      -0.001    FALSE     FALSE      FALSE     TRUE
#>     -0.005      -0.001    FALSE     FALSE      FALSE     TRUE
#>     -0.042      -0.001    FALSE      TRUE       TRUE     TRUE
#> 
#> Settings
#>         Setting Value
#>     theta_range -6, 6
#>    theta_points   241
#>     drop_unused FALSE
#>   include_fixed FALSE
#>  fixed_max_rows   200
#> 
#> Notes
#>  - Category-structure diagnostics with mode boundaries and half-score reference points.
names(out)
#> [1] "category_table"        "mode_peaks"            "mode_boundaries"      
#> [4] "median_thresholds"     "mean_halfscore_points" "settings"             
p_cs <- plot(out, draw = FALSE)
class(p_cs)
#> [1] "mfrm_plot_data" "list"