Re-estimates a many-facet Rasch model on new data while holding selected facet parameters fixed at the values from a previous (baseline) calibration. This is the standard workflow for placing new data onto an existing scale, linking test forms, or carrying a baseline calibration across administration windows.
Usage
anchor_to_baseline(
new_data,
baseline_fit,
person,
facets,
score,
anchor_facets = NULL,
include_person = FALSE,
weight = NULL,
model = NULL,
method = NULL,
anchor_policy = "warn",
...
)
# S3 method for class 'mfrm_anchored_fit'
print(x, ...)
# S3 method for class 'mfrm_anchored_fit'
summary(object, ...)
# S3 method for class 'summary.mfrm_anchored_fit'
print(x, ...)Arguments
- new_data
Data frame in long format (one row per rating).
- baseline_fit
An
mfrm_fitobject from a previous calibration.- person
Character column name for person/examinee.
- facets
Character vector of facet column names.
- score
Character column name for the rating score.
- anchor_facets
Character vector of facets to anchor (default: all non-Person facets).
- include_person
If
TRUE, also anchor person estimates.- weight
Optional character column name for observation weights.
- model
Scale model override; defaults to baseline model.
- method
Estimation method override; defaults to baseline method.
- anchor_policy
How to handle anchor issues:
"warn","error","silent".- ...
Ignored.
- x
An
mfrm_anchored_fitobject.- object
An
mfrm_anchored_fitobject (forsummary).
Value
Object of class mfrm_anchored_fit with components:
- fit
The anchored
mfrm_fitobject.- diagnostics
Output of
diagnose_mfrm()on the anchored fit.- baseline_anchors
Anchor table extracted from the baseline.
- drift
Tibble of element-level drift statistics.
Details
This function automates the baseline-anchored calibration workflow:
Extracts anchor values from the baseline fit using
make_anchor_table().Re-estimates the model on
new_datawith those anchors fixed viafit_mfrm(..., anchors = anchor_table).Runs
diagnose_mfrm()on the anchored fit.Computes element-level differences (new estimate minus baseline estimate) for every common element.
The model and method arguments default to the baseline fit's settings
so the calibration framework remains consistent. Elements present in the
anchor table but absent from the new data are handled according to
anchor_policy: "warn" (default) emits a message, "error" stops
execution, and "silent" ignores silently.
The returned drift table is best interpreted as an anchored consistency
check. When a facet is fixed through anchor_facets, those anchored levels
are constrained in the new run, so their reported differences are not an
independent drift analysis. For genuine cross-wave drift monitoring, fit the
waves separately and use detect_anchor_drift() on the resulting fits.
Element-level differences are calculated for every element that appears in both the baseline and the new calibration: $$\Delta_e = \hat{\delta}_{e,\text{new}} - \hat{\delta}_{e,\text{base}}$$ An element is flagged when \(|\Delta_e| > 0.5\) logits or \(|\Delta_e / SE_{\Delta_e}| > 2.0\), where \(SE_{\Delta_e} = \sqrt{SE_{\mathrm{base}}^2 + SE_{\mathrm{new}}^2}\).
Which function should I use?
Use
anchor_to_baseline()when you have one new dataset and want to place it directly on a baseline scale.Use
detect_anchor_drift()when you already have multiple fitted waves and want to compare their stability.Use
build_equating_chain()when you need cumulative offsets across an ordered series of waves.
Interpreting output
$drift: one row per common element with columnsFacet,Level,Baseline,New,Drift,SE_Baseline,SE_New,SE_Diff,Drift_SE_Ratio, andFlag. Read this as an anchored consistency table. Small absolute differences indicate that the anchored re-fit stayed close to the baseline scale. Flagged rows warrant review, but they are not a substitute for a separate drift study on unanchored common elements.$fit: the full anchoredmfrm_fitobject, usable withdiagnose_mfrm(),measurable_summary_table(), etc.$diagnostics: pre-computed diagnostics for the anchored calibration.$baseline_anchors: the anchor table fed tofit_mfrm(), useful for auditing which elements were constrained.
Typical workflow
Fit the baseline model:
fit1 <- fit_mfrm(...).Collect new data (e.g., a later administration).
Call
res <- anchor_to_baseline(new_data, fit1, ...).Inspect
summary(res)to confirm the anchored run remains close to the baseline scale.For multi-wave drift monitoring, fit waves separately and pass the fits to
detect_anchor_drift()orbuild_equating_chain().
Examples
d1 <- load_mfrmr_data("study1")
keep1 <- unique(d1$Person)[1:15]
d1 <- d1[d1$Person %in% keep1, , drop = FALSE]
fit1 <- fit_mfrm(d1, "Person", c("Rater", "Criterion"), "Score",
method = "JML", maxit = 15)
#> Warning: Optimizer did not fully converge (code = 1). Consider increasing maxit (current: 15) or relaxing reltol (current: 1e-06).
d2 <- load_mfrmr_data("study2")
keep2 <- unique(d2$Person)[1:15]
d2 <- d2[d2$Person %in% keep2, , drop = FALSE]
res <- anchor_to_baseline(d2, fit1, "Person",
c("Rater", "Criterion"), "Score",
anchor_facets = "Criterion")
#> Warning: Anchor audit detected 3 issue row(s): unknown_anchor_levels=3. Invalid rows were removed; duplicate keys keep the last row.
summary(res)
#> --- Anchored Fit Summary ---
#> Converged: TRUE
#> Anchors used: 3 | Common elements: 0 | Flagged: 0
#>
head(res$drift[, c("Facet", "Level", "Drift", "Flag")])
#> # A tibble: 0 × 4
#> # ℹ 4 variables: Facet <chr>, Level <chr>, Drift <dbl>, Flag <lgl>
res$baseline_anchors[1:3, ]
#> # A tibble: 3 × 3
#> Facet Level Anchor
#> <chr> <chr> <dbl>
#> 1 Criterion Global_Impression -1.07
#> 2 Criterion Linguistic_Realization 0.585
#> 3 Criterion Task_Fulfillment 0.487