The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Migrating from Facets to mfrmr

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.

Mental model

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:

facets_feature_coverage()
facets_feature_coverage("not_implemented")
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()

A one-shot legacy-compatible call

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:

summary(run$fit)
head(run$fair_average)

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.

Translating the specification file

The mapping below covers the most common Facets specification keywords.

Facets and labels

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).

Anchoring

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.

Bias and interaction

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.

Wright map / variable map

For a shared-logit visual display of persons, facet levels, and step thresholds, use the Wright map route:

plot(fit, type = "wright", preset = "publication", show_ci = TRUE)

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.

Fit df and ZSTD review

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.

Group anchoring and DFF

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")

Reviewing output contracts and fit tables

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_checks

The 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.

Producing Facets-style output files

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.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.