Legacy-compatible residual diagnostics can be inspected in two ways:
overall residual PCA on the person x combined-facet matrix
facet-specific residual PCA on person x facet-level matrices
Usage
analyze_residual_pca(
diagnostics,
mode = c("overall", "facet", "both"),
facets = NULL,
pca_max_factors = 10L
)Arguments
- diagnostics
Output from
diagnose_mfrm()orfit_mfrm().- mode
"overall","facet", or"both".- facets
Optional subset of facets for facet-specific PCA.
- pca_max_factors
Maximum number of retained components.
Value
A named list with:
mode: resolved mode used for computationfacet_names: facets analyzedoverall: overall PCA bundle (orNULL)by_facet: named list of facet PCA bundlesoverall_table: variance table for overall PCAby_facet_table: stacked variance table across facets
Details
The function works on standardized residual structures derived from
diagnose_mfrm(). When a fitted object from fit_mfrm() is supplied,
diagnostics are computed internally.
Conceptually, this follows the Rasch residual-PCA tradition of examining
structure in model residuals after the primary Rasch dimension has been
extracted. In mfrmr, however, the implementation is an exploratory
many-facet adaptation: it works on standardized residual matrices built as
person x combined-facet or person x facet-level layouts, rather than
reproducing FACETS/Winsteps residual-contrast tables one-to-one.
Output tables use:
Component: principal-component index (1, 2, ...)Eigenvalue: eigenvalue for each componentProportion: component variance proportionCumulative: cumulative variance proportion
For mode = "facet" or "both", by_facet_table additionally includes
a Facet column.
summary(pca) is supported through summary().
plot(pca) is dispatched through plot() for class
mfrm_residual_pca. Available types include "overall_scree",
"facet_scree", "overall_loadings", and "facet_loadings".
Interpreting output
Use overall_table first:
early components with noticeably larger eigenvalues or proportions suggest stronger residual structure that may deserve follow-up.
Then inspect by_facet_table:
helps localize which facet contributes most to residual structure.
Finally, inspect loadings via plot_residual_pca() to identify which
variables/elements drive each component.
References
The residual-PCA idea follows the Rasch residual-structure literature,
especially Linacre's discussions of principal components of Rasch residuals.
The current mfrmr implementation should be interpreted as an exploratory
extension for many-facet workflows rather than as a direct reproduction of a
single FACETS/Winsteps output table.
Linacre, J. M. (1998). Structure in Rasch residuals: Why principal components analysis (PCA)? Rasch Measurement Transactions, 12(2), 636.
Linacre, J. M. (1998). Detecting multidimensionality: Which residual data-type works best? Journal of Outcome Measurement, 2(3), 266-283.
Typical workflow
Fit model and run
diagnose_mfrm()withresidual_pca = "none"or"both".Call
analyze_residual_pca(..., mode = "both").Review
summary(pca), then plot scree/loadings.Cross-check with fit/misfit diagnostics before conclusions.
Examples
toy <- load_mfrmr_data("example_core")
fit <- fit_mfrm(toy, "Person", c("Rater", "Criterion"), "Score", method = "JML", maxit = 25)
diag <- diagnose_mfrm(fit, residual_pca = "both")
pca <- analyze_residual_pca(diag, mode = "both")
pca2 <- analyze_residual_pca(fit, mode = "both")
summary(pca)
#> mfrmr Residual PCA Summary
#> Class: mfrm_residual_pca
#> Components (7): mode, facet_names, overall, by_facet, overall_table, by_facet_table, errors
#>
#> PCA overview
#> Mode Facets OverallComponents FacetComponentRows
#> both 2 16 8
#>
#> Eigenvalue / loading rows: overall_table
#> Component Eigenvalue Proportion Cumulative
#> 1 2.113 0.132 0.132
#> 2 1.833 0.115 0.247
#> 3 1.706 0.107 0.353
#> 4 1.519 0.095 0.448
#> 5 1.290 0.081 0.529
#> 6 1.157 0.072 0.601
#> 7 1.098 0.069 0.670
#> 8 1.055 0.066 0.736
#> 9 0.949 0.059 0.795
#> 10 0.846 0.053 0.848
#>
#> Notes
#> - Residual PCA summary for unidimensionality checks (overall and/or by facet).
p <- plot_residual_pca(pca, mode = "overall", plot_type = "scree", draw = FALSE)
class(p)
#> [1] "mfrm_plot_data" "list"
head(p$data)
#> $plot
#> [1] "scree"
#>
#> $mode
#> [1] "overall"
#>
#> $facet
#> NULL
#>
#> $title
#> [1] "Overall Residual PCA (Scree)"
#>
#> $subtitle
#> [1] "Variance explained by residual components"
#>
#> $legend
#> label role aesthetic value
#> 1 Residual eigenvalues component line-point #1f78b4
#> 2 Unit-eigenvalue reference reference line #6b7280
#>
head(pca$overall_table)
#> Component Eigenvalue Proportion Cumulative
#> 1 1 2.113455 0.13209091 0.1320909
#> 2 2 1.833187 0.11457417 0.2466651
#> 3 3 1.706146 0.10663410 0.3532992
#> 4 4 1.519040 0.09494001 0.4482392
#> 5 5 1.289522 0.08059513 0.5288343
#> 6 6 1.157161 0.07232254 0.6011568