Skip to contents

Compute displacement diagnostics for facet levels

Usage

displacement_table(
  fit,
  diagnostics = NULL,
  facets = NULL,
  anchored_only = FALSE,
  abs_displacement_warn = 0.5,
  abs_t_warn = 2,
  top_n = NULL
)

Arguments

fit

Output from fit_mfrm().

diagnostics

Optional output from diagnose_mfrm(). Must match this fitted analysis; see mfrmr_compatibility_layer for migration of saved diagnostics.

facets

Optional subset of facets.

anchored_only

If TRUE, keep only directly/group anchored levels.

abs_displacement_warn

Absolute displacement warning threshold.

abs_t_warn

Absolute displacement t-value warning threshold.

top_n

Optional maximum number of rows to keep after sorting.

Value

A named list with:

  • table: displacement diagnostics by level

  • summary: one-row summary

  • thresholds: applied thresholds

Details

Displacement is computed as a one-step Newton update: sum(residual) / sum(information) for each facet level. This approximates how much a level would move if constraints were relaxed.

Interpreting output

  • table: level-wise displacement and flag indicators.

  • summary: count/share of flagged levels.

  • thresholds: displacement and t-value cutoffs.

Large absolute displacement in anchored levels suggests potential instability in anchor assumptions.

Typical workflow

  1. Run displacement_table(fit, anchored_only = TRUE) for anchor checks.

  2. Inspect summary(disp) then detailed rows.

  3. Visualize with plot(x, type = "displacement").

Output columns

The table data.frame contains:

Facet, Level

Facet name and element label.

Displacement

One-step Newton displacement estimate (logits).

DisplacementSE

Standard error of the displacement.

DisplacementT

Displacement / SE ratio.

Estimate, SE

Current measure estimate and its standard error.

N

Number of observations involving this level.

AnchorValue, AnchorStatus, AnchorType

Anchor metadata.

Flag

Logical; TRUE when displacement exceeds thresholds.

Saved-result reuse

The returned fit_identity records the fitted analysis for reuse with reports and exports. Recreate older results from the saved fit and matching diagnostics using the original screening options; no model refit is needed. See mfrmr_compatibility_layer for migration instructions.

Examples

# Saved synthetic JML/RSM analysis of example_core.
# For your own data, fit a model first; see ?fit_mfrm.
example_fit <- readRDS(system.file("examples", "core-jml.rds", package = "mfrmr"))
fit <- example_fit$fit
disp <- displacement_table(fit, anchored_only = FALSE)
summary(disp)
#> mfrmr Displacement Summary 
#>   Class: mfrm_displacement
#>   Components: 4
#> 
#> Displacement summary
#>  Levels AnchoredLevels FlaggedLevels FlaggedAnchoredLevels MaxAbsDisplacement
#>      56              0             0                     0                  0
#>  MaxAbsDisplacementT AbsDisplacementThreshold AbsTThreshold
#>                    0                      0.5             2
#> 
#> Displacement rows: table
#>   Facet        Level WeightedN ResidualSum Information FacetSign Displacement
#>  Person <suppressed>        16           0       3.461         1            0
#>  Person <suppressed>        16           0       6.761         1            0
#>  Person <suppressed>        16           0       9.206         1            0
#>  Person <suppressed>        16           0       9.206         1            0
#>  Person <suppressed>        16           0       9.206         1            0
#>  Person <suppressed>        16           0       9.183         1            0
#>  Person <suppressed>        16           0       9.453         1            0
#>  Person <suppressed>        16           0       9.453         1            0
#>  Person <suppressed>        16           0       4.967         1            0
#>  Person <suppressed>        16           0       6.553         1            0
#>  DisplacementSE DisplacementT Estimate    SE  N AnchorValue AnchorStatus
#>           0.538             0    2.684 0.538 16          NA             
#>           0.385             0   -1.665 0.385 16          NA             
#>           0.330             0    0.791 0.330 16          NA             
#>           0.330             0    0.791 0.330 16          NA             
#>           0.330             0    0.791 0.330 16          NA             
#>           0.330             0   -0.918 0.330 16          NA             
#>           0.325             0    0.684 0.325 16          NA             
#>           0.325             0    0.684 0.325 16          NA             
#>           0.449             0   -2.178 0.449 16          NA             
#>           0.391             0    1.672 0.391 16          NA             
#>  AnchorType ReleasedEstimate AnchorGap FlagDisplacement FlagT  Flag
#>        Free            2.684        NA            FALSE FALSE FALSE
#>        Free           -1.665        NA            FALSE FALSE FALSE
#>        Free            0.791        NA            FALSE FALSE FALSE
#>        Free            0.791        NA            FALSE FALSE FALSE
#>        Free            0.791        NA            FALSE FALSE FALSE
#>        Free           -0.918        NA            FALSE FALSE FALSE
#>        Free            0.684        NA            FALSE FALSE FALSE
#>        Free            0.684        NA            FALSE FALSE FALSE
#>        Free           -2.178        NA            FALSE FALSE FALSE
#>        Free            1.672        NA            FALSE FALSE FALSE
#> 
#> Settings
#>                Setting Value
#>  abs_displacement_warn   0.5
#>             abs_t_warn     2
#> 
#> Notes
#>  - Displacement summary for anchor drift and baseline drift checks.
#>  - Person identifiers are suppressed in this summary. Use `include_person =
#>    TRUE` only under appropriate privacy controls.
p_disp <- plot(disp, draw = FALSE)
p_disp$data$plot
#> [1] "lollipop"