This vignette walks Facets users through the equivalent
mfrmr workflow: preparing data, fitting an
RSM/PCM many-facet Rasch-family model with
Facets-compatible defaults, generating the diagnostic and reporting
tables that the canonical Facets output stack provides, and reviewing
the output-contract boundary between the two systems. Bounded
GPCM can be fit in mfrmr, but its slope-aware
score semantics are intentionally outside the score-side Facets
output-contract route.
The two stacks share the same psychometric framework but differ in operating model.
Before treating a legacy workflow as covered, inspect the public coverage boundary:
| Concept | Facets (Linacre 2026) | mfrmr |
|---|---|---|
| Input | Specification file plus data file | data.frame in long format |
| Estimation | JMLE by default | JML (legacy default) or MML (recommended
for new analyses) |
| Models | Rating-scale, partial-credit, polytomous step models | RSM, PCM, bounded GPCM |
| Output | Tables 0-30 plus graphic files | Returned R objects with summary() and
plot() methods |
| Anchoring | D=, A= fields in the specification |
anchors and group_anchors arguments to
fit_mfrm() |
| Bias / interaction | Table 14 | estimate_bias() and
bias_interaction_report() |
| Wright map / variable map | Graphic variable-map output | plot(fit, type = "wright") and
plot_wright_unified() |
| Fair average | Table 7 fair-M average | fair_average_table() |
| Reproducibility | Specification file is the manifest | build_mfrm_manifest() plus
build_mfrm_replay_script() |
If the goal is to reproduce a Facets-style script with minimal R-side
plumbing, use run_mfrm_facets() (alias
mfrmRFacets()):
library(mfrmr)
data("ej2021_study1", package = "mfrmr")
run <- run_mfrm_facets(
data = ej2021_study1,
person = "Person",
facets = c("Rater", "Criterion"),
score = "Score",
model = "RSM",
method = "JML"
)
names(run)The wrapper returns the same fit_mfrm() and
diagnose_mfrm() objects that a step-by-step pipeline
produces, plus the iteration log, fair-average table, and rating-scale
table:
For new analysis scripts, prefer
fit_mfrm(method = "MML") directly. MML integrates over the
person distribution under an N(0, 1) prior and exposes per-person
posterior SEs that JML cannot produce.
The mapping below covers the most common Facets specification keywords.
Facets = 3
Models = ?,?,?,R5
Labels =
1, Examinee
1 = P01
...
2, Rater
1 = R1
...
3, Criterion
1 = Content
...
translates to:
fit_mfrm(
data = examinee_long,
person = "Examinee",
facets = c("Rater", "Criterion"),
score = "Score",
rating_min = 1,
rating_max = 5,
model = "RSM"
)Models = ?,?,?,R5 becomes model = "RSM" and
the R5 rating-scale declaration becomes
rating_min = 1, rating_max = 5. For a partial-credit
specification, pass model = "PCM" and identify the facet
that carries the step thresholds with step_facet = "Rater"
(or the appropriate facet name).
A Facets D = 2, A = block:
D = 2
A = 1, 0.0
2, 0.5
becomes an anchors data frame:
anchors <- data.frame(
facet = "Rater",
level = c("R1", "R2"),
estimate = c(0.0, 0.5),
stringsAsFactors = FALSE
)
fit <- fit_mfrm(..., anchors = anchors)review_mfrm_anchors() validates and reports on the
anchor block before the fit runs, surfacing connectivity, overlap, and
minimum-sample issues.
Facets Table 14 bias output between Rater and Criterion has a direct equivalent:
diag <- diagnose_mfrm(fit)
bias <- estimate_bias(fit, diag,
facet_a = "Rater", facet_b = "Criterion")
summary(bias)estimate_all_bias() enumerates every non-person facet
pair in one call.
For a shared-logit visual display of persons, facet levels, and step thresholds, use the Wright map route:
plot_wright_unified() is the corresponding explicit
helper when the Wright map is the main figure rather than one panel in a
larger visual workflow. Use draw = FALSE or
plot_data(fit, type = "wright") when you need the
underlying coordinates for a custom ggplot2, base-R, or
Quarto graphic.
Facets users often compare Infit/Outfit MnSq together with ZStd
columns. In mfrmr, treat MnSq as the primary fit statistic
and use the df/ZSTD columns to explain how the same MnSq values were
standardized. The direct review path is:
diag <- diagnose_mfrm(fit, residual_pca = "none", fit_df_method = "both")
fm <- fit_measures_table(fit, diagnostics = diag,
facet = "Rater", fit_df_method = "both")
fm$facets_table
fm$df_sensitive
plot(fm, type = "df_sensitivity")df_sensitivity reports the engine-vs-FACETS-style df
comparison row by row; df_sensitive keeps only rows where
the df convention changes the |ZSTD| flag or materially changes the ZSTD
interpretation. The same status taxonomy is used by
facets_fit_review(), so a table-oriented review and an
external FACETS comparison use the same language.
Facets D = ..., G = group-anchor blocks for differential
facet functioning translate to the group_anchors argument
and the analyze_dff() follow-up:
group_anchors <- data.frame(
facet = "Criterion",
level = "Content",
group = c("Native", "Non-native"),
estimate = c(0.0, 0.0),
stringsAsFactors = FALSE
)
fit_g <- fit_mfrm(..., group_anchors = group_anchors)
dff <- analyze_dff(fit_g, diag, facet = "Criterion",
group = "FirstLanguage", method = "refit")When migrating an existing study,
facets_output_contract_review() checks whether the
package-generated report components satisfy the FACETS-style output
contract encoded in the package:
contract_review <- facets_output_contract_review(
fit,
diagnostics = diag,
branch = "facets"
)
summary(contract_review)
contract_review$missing_preview
contract_review$metric_checksThe resulting object reviews column coverage and package-native
metric checks. It is not a claim that mfrmr has reproduced
FACETS estimates numerically. For external numerical comparison, use an
exported FACETS fit table and facets_fit_review().
If you already have a FACETS fit table on disk, read it first and then run the fit review. This does not run FACETS; it consumes an exported or otherwise harmonized table.
facets_fit <- read_facets_fit_table(
"score.2.txt",
facet_map = c("1" = "Person", "2" = "Rater", "3" = "Criterion")
)
review <- facets_fit_review(
fit,
diagnostics = diag,
facets_fit = facets_fit,
external_zstd_tolerance = 0.05
)
review$df_sensitivity
review$df_sensitive
review$external_table_quality
review$external_comparison
plot(review, type = "df_sensitivity")Use external_comparison for the supplied FACETS table
and df_sensitivity for the engine-vs-FACETS-style df
convention check. This separation keeps external numerical differences
distinct from ZSTD differences caused by df standardization.
external_table_quality is the first place to look if the
FACETS export only contains ZStd and T.Count columns, or if duplicate
Facet x Level rows were supplied.
For traceability or downstream tools that expect Facets output files,
facets_output_file_bundle() writes a parallel set of
fixed-width or CSV exports:
files <- facets_output_file_bundle(
fit,
diagnostics = diag,
out_dir = tempdir(),
include = c("graph", "score")
)For RSM and PCM the score-side helpers are available. Under bounded
GPCM the score-side bundle is intentionally restricted; see
?gpcm_capability_matrix and the
mfrmr-gpcm-scope vignette for the binding contract.
After a Facets-equivalent fit is in hand, the canonical mfrmr reporting route extends the analysis with:
review_mfrm_anchors() before anchored fitting, and
detect_anchor_drift() / plot_anchor_drift()
when common elements define a cross-form or cross-wave link.diagnose_mfrm(diagnostic_mode = "both") for the strict
marginal screen alongside the residual stack.rating_scale_table(),
category_structure_report(), and
category_curves_report() for category-functioning
evidence.fair_average_table() when FACETS Table 12-style
fair-average review is needed.plot(fit, type = "wright") or
plot_wright_unified() for a variable-map view of targeting
and threshold placement.estimate_bias(),
bias_interaction_report(), and
bias_pairwise_report() when FACETS Table 14-style local
interaction screening is substantively relevant.reporting_checklist() for a manuscript-readiness
summary.build_apa_outputs() for Method and Results paragraphs
and APA tables.build_mfrm_manifest() and
build_mfrm_replay_script() for the reproducibility bundle
that Facets specifications cannot produce out of the box.The mfrmr-workflow vignette covers the full sequence end
to end; the mfrmr-reporting-and-apa vignette focuses on the
manuscript surface; the mfrmr-linking-and-dff vignette
covers anchoring, drift, and DFF in detail.