nomologR 0.9.0 is the last minor release before 1.0.0, the stable release planned
jointly with contentvalidR (#53). It carries the 1.0 scope selected so far
(#113); what is added before the release candidate on 2026-10-17 is recorded
there. It is about how the package presents itself and what it teaches:
print() and summary() is redesigned
(#89): aligned tables with the columns that matter, explanations in full,
APA-style numbers, and one flag wording ("review", "concern") in the console,
plots, and reports.nomo_methods() gives the year each
method entered the literature and, for a historical method, the contemporary
methods that took over its question. The research-basis article draws them
into a timeline.contentvalidR review's
items through the screen, on the joint walkthrough's data, now shipped as
nomo_demo_walkthrough (#60).nomo_apa_table() formats
nomo_validity() results: each construct pair's latent correlation with its
interval beside HTMT2, and a table of AVE.No computed estimate changes. Compared value by value with 0.3.0 across 22 analyses spanning every stage, every estimate is identical. What differs:
nomo_screen() reviews each item within
its own scale: its item-rest correlation against the rest of that scale
(scale, scale_item_rest_r, scale_item_rest_n), and its negative
inter-item correlations only with items of the same scale
(scale_negative_interitem_n). Which items are flagged can change.
corrected_item_rest_r and negative_interitem_n are unchanged.nomo_validity() result, latent_correlations$block names
the groups by label rather than by number.Breaking changes.
nomo_missing() takes the fitted model as fit rather than x (#114). Calls
that pass the model first without naming it are unaffected. The function was
marked experimental, so there is no deprecation period.nomo_screen() checks scales when effort = FALSE too, since the
within-scale correlations use it. A scales that names items not being
screened now stops with an error instead of being ignored.nomo_report(apa_tables = TRUE) adds the validity tables, and when the run
has a validity stage, its construct-pair table takes the place of the CFA
factor correlations.method must be one of ...", instead of base R's "'arg' should be one of".
Only code that matches the old message text would notice.nomologR 0.3.0 is still in CRAN's queue for new submissions (#39); until CRAN accepts it, install from R-universe or GitHub.
nomo_demo_network, social desirability is uncorrelated with the other two constructs by design, and its near-zero negative correlations with their items had flagged all eight Agency and Persistence items. relationship_summary gains scale_negative_interitem_n. negative_interitem_n and inter_item_correlations are unchanged. Negative correlations between scales are logged as information (negative_pairs_between_scales). The log entry for negative pairs now agrees in number: "1 estimable inter-item correlation is negative".nomo_apa_table() formats a nomo_validity() result (#113). type = "discriminant", the default, gives each pair of constructs one row: its latent correlation with a 95% confidence interval (Rönkkö & Cho, 2022), beside HTMT2 (Roemer et al., 2021) and HTMT (Henseler et al., 2015) when they were computed. type = "convergent" gives each construct's number of indicators and AVE. The pair table is deliberately not the Fornell-Larcker matrix with the square root of AVE on its diagonal, the comparison that nomo_methods() records as historical because it often misses constructs that are not distinct. Correlations and AVE lose their leading zero; the ratios, which can exceed 1, keep it. A multi-group model's tables add a Group column. nomo_report(apa_tables = TRUE) adds both tables after reliability, and the pair table takes the place of the CFA factor correlations, which it repeats.nomo_validity() result, latent_correlations names its groups (block) by their labels, as ave does, rather than by number. lavaan::standardizedSolution() numbers the groups, so the two tables of one result had disagreed, for example "1" and "2" against "Pasteur" and "Grant-White".scales or a contentvalidR handoff, the item audit reads each item's corrected item-rest correlation within its own scale (#113). An item is scored on its scale's total, so the rest of that scale is what it has to agree with (Nunnally & Bernstein, 1994; Clark & Watson, 2019). Pooled across constructs, the items of a distinct scale look weak: in nomo_demo_network, the three social-desirability items correlate .15 to .17 with the rest of all eleven items and were flagged, and .52 to .57 with the rest of their own scale. The relationship summary gains scale, scale_item_rest_r, and scale_item_rest_n, and corrected_item_rest_r keeps the pooled value. The flag, the decision-log entry (which names the scale), the summary table, and the item-rest plot use the within-scale value. A guided run's per-scale audits were already within-scale; the instrument-wide audit that settings$screen$effort = TRUE adds now agrees with them. scales is checked when effort = FALSE too, since it now matters there.nomo_missing() takes the fitted model as fit, as nomo_reliability(), nomo_validity(), nomo_scores(), and nomo_hierarchical() do (#114). It had been x. The function is experimental until 1.0.0, so the name changes without a deprecation period. Calls that pass the model first, without naming it, are unaffected.$, which warns on a tibble.nomo_methods() in a course.nomo_methods() records how practice changed (#113). introduced is the year a method entered the literature, taken from the publication that introduced it, and given only when the registry cites that publication (46 of 89 methods so far). contemporary_practice names, for a historical method, the contemporary methods that now answer its question: parallel analysis for the eigenvalue-greater-than-one rule, omega for coefficient alpha, HTMT2 and latent-correlation intervals for the Fornell-Larcker comparison, FIML for listwise deletion. The research-basis article gains a section, "How practice changed", with a timeline from 1937 to 2022 and a table of what took over from each historical method, both drawn from the registry. The KMO entry now cites Kaiser (1970), which introduced the index. The methods table in nomo_report() shows the year each method was introduced, so an archived report carries the same record.standardized_loadings and fit_evidence on a nomo_cfa, were not named in the contract. Each Value section now lists the fields to read, one line each, and says that the remaining fields (the call, settings, and engine intermediates) are not part of the stable interface. This changes documentation only. ?nomo_efa no longer explains factor_count with an internal milestone label.contentvalidR review carried forward through the empirical screen, on the shared teaching data of the joint walkthrough (#60, #53). It shows the two stages disagreeing, which is the reason the pair exists. EF4 passes content review and carries almost no common variance. EF3 is flagged empirically but is the only item covering part of the domain. TF4 loads on both facets, and TF6 is not invariant across cohorts. The article builds without contentvalidR installed.nomo_demo_walkthrough and nomo_demo_walkthrough_items: 400 simulated responses to twelve Study Persistence items in two cohorts, with each item's built-in role (#60). They are contentvalidR's walkthrough files, copied unchanged from its v0.9.0 release with their git blob hashes. contentvalidR's generator is in data-raw/walkthrough/.contentvalidR handoff or by reverse (#60). It says the sign is what such an item shows before recoding, and gives the item-rest correlation computed on a copy recoded as declared. If the recoded correlation is still negative, it says the keying does not explain it. nomo_run() passes a handoff's declared keying to each scale's audit for this. The data, the returned correlation, and the flag are unchanged; nomologR never recodes data.nomo_demo_network, the known ag3 intercept (score 61) had been hidden behind a metric loading (score 5).item_type is unchanged. The missing-data print says why a strategy was not fitted, such as "FIML: Not fitted: no modeled variable has missing values." for complete data, and shows its N as "-" rather than NA.nomo_scores(fit, method = "eap") now stops with "method must be one of "sum", "mean", "regression", or "bartlett", not "eap"." instead of base R's "'arg' should be one of …". This applies to every argument with a fixed set of values, such as type in plot(), nomo_table(), and nomo_apa_table(). Partial matching (type = "load") works as before.nomo_cfa() says when its fit indices cannot test the model (#89). A one-factor model with three indicators is just identified (df = 0): it reproduces the covariances by construction, and its print had shown "RMSEA 0.000 | SRMR 0.000" like a well-fitting model. A model with negative degrees of freedom, such as a factor with two indicators, is not identified. The print now reads "Fit: not testable (df = 0, just identified)", the summary explains why, and the guided run's key evidence says the same. The decision log's degrees-of-freedom entry, which was already recorded, now names the case, and a model that is not identified is a concern rather than a review. Warnings that lavaan raises while nomologR reads the results, such as "Could not compute standard errors", are kept with the model's engine warnings instead of printing at the console. The "NaNs produced" warnings that lavaan::fitMeasures() raises for negative degrees of freedom are no longer shown.KEEP and REVIEW under "Review", and the validity plots info and review under "Signal". The item evidence map calls an informational signal a "note", which is how the console shows it. Each flag level keeps the same point shape from plot to plot.print() and summary() for nomo_run() (#89). The print opens with the run's status, mode, sample design, and scales, then lists what the run found so far as "Key evidence" (item flags, suggested factors, CFA fit, the omega range, validity and invariance results). A request repeated for several scales, such as a factor-count decision for each of three scales, is shown once with the scales it applies to, rather than once per scale. Research mode leaves out the teaching-mode reason, options, and consequences, and keeps what each scale showed and an example. The summary is about a third of its former length: a stage table, recorded decisions as bullets, the component recipe, and a count of the methods used with the primary method of each stage, pointing to nomo_methods() and nomo_table() for the full entries. The gallery in dev/output-gallery.R now reports no presentation faults.nomo_report() tables are easier to read (#89). Column headings are words, not code names: "Omega CI lower" for omega_ci_lower, "Change in CFI" for delta_cfi, "Corrected item-rest r" for corrected_item_rest_r. Flags use the console's wording ("review", "concern"). A missing or empty cell is an em dash rather than NA or nothing, and TRUE/FALSE is yes/no. Item, scale, and factor names are left as written. The values are otherwise unchanged, and nomo_table() still returns the code's column names and flag values. The citations table gives each package's reference as text. It had held R's whole print(citation()) output, including a BibTeX entry whose @Manual{ pandoc turned into a stray citation, and LaTeX such as \texttt{semTools}.nomo_apa_table() (#89).
review: and concern: bullets. Index names read as written in the literature ("omega hierarchical", "ECV"). A column that holds one value throughout, such as a block column that always says "overall", is left out. The note on correlational accuracy names the pair of factors whose score correlation strays furthest from the factor correlation. It had named one of the two, and which one depended on rounding, so it differed between platforms.contentvalidR 0.8.0 and 0.9.0 output as well as 0.6.0 and 0.7.0 (#53). The added fixtures include a nine-expert panel whose carry decision changed between producers. Seven of nine experts rate item N7 relevant, which is what Lynn (1986) requires. contentvalidR 0.7.0 compared the I-CVI with a rounded .78 and held N7 back; 0.8.0 compares counts and carries it. The test confirms that nomo_screen() follows the decision the handoff records rather than inferring one from the producer version. The reader needed no change: 0.8.0 and 0.9.0 keep schema version 1 with the same fields and columns.print() and summary() for nomo_screen(), nomo_factors(), and nomo_efa(). The screen summary lists each flagged item with the decision log's own explanation rather than internal metric names. The factor-retention summary prints the reason a criterion was not run, and the Bartlett result, in full rather than cut off in a table cell. The EFA summary no longer hides the item flags behind "2 more variables".nomo_cfa()'s print() and summary(). Tables are aligned text with the columns that matter and no type rows. A flagged loading's explanation is printed in full rather than cut off inside a table cell. Numbers have fixed decimals, p-values follow APA style, and prose wraps to the console width. Flags are shown in one wording across the package: nothing for no flag, then "review", then "concern". This is display only: returned objects, nomo_table() types, and decision-log values keep their values. dev/output-gallery.R regenerates every print, summary, and plot and reports the remaining presentation faults.nomo_cfa(), nomo_invariance(), and nomo_network() name any variable the model uses that the data lack, before fitting (#89): "model names variable(s) not found in data: agX. Check the spelling against names(data)." A misspelled item had reached lavaan, and the error named lavaan's internal step (lavaan->lav_step02_options()) rather than the item. The more specific argument checks, such as for ordered, still come first, and model syntax that lavaan cannot parse is still reported by lavaan.nomo_table() works on every measurement-stage result: nomo_factors, nomo_efa, nomo_cfa, nomo_reliability, and nomo_validity (#89). They had no method, so the documented way to extract a table failed for five of the package's main results. Each returns the tables its report section shows. nomo_report() now gets them through nomo_table(), so the two cannot drift apart. ?nomo_table lists every supported object and type, including nomo_screen and nomo_scores, which were missing from it.plot(<nomo_screen>, type = "responses") draws a histogram for a continuous item (#89). It drew a bar for every distinct value, which for continuous responses means one bar per respondent: an unreadable plot, with a percentage label on each bar. Categorical items keep their bars. When the selected items mix the two, the categorical items are drawn and the caption names the continuous ones and how to plot them.nomo_validity() lists each construct pair once in its print, summary, and report section, with the latent correlation and HTMT-family values in the same row (#89). Latent correlations name a pair in model order and HTMT names it the other way round, so the two never merged. Each pair appeared twice, once with its correlation but a signal of "unavailable" and once with its HTMT values, and the print counted twice as many pairs as there are. Pairs are now shown in model order, including in the HTMT plot. The returned tables and every computed value are unchanged.nomo_report() headings are rendered for every scale of a multi-scale run (#89). A heading that followed a plot, which is every scale after the first in the item audit and factor retention, plus "Careless responding", was run into the plot's paragraph. It appeared as literal ## Scale: ... text in HTML and Word, and the table of contents filed every scale's tables under the first. The report tests had rendered only single-scale runs or had turned plots off; a two-scale report with plots is now tested in both formats.<report_dir>. It had printed the full temporary path of the computer that built the article, including a user name, and the path changed on every build. The message still comes from nomo_report(), and the example still shows that an existing report is refused unless overwrite = TRUE is given.nomologR 0.3.0 is the first release submitted to CRAN (#39), and its scope was kept deliberately lean for that reason (#38). It does three things:
contentvalidR now flows into nomo_screen() and nomo_run(), and the
reasons for each item's carry decision travel with it (#46).?nomologR (#74).Test coverage is back to every executable line (#72). Reviewing each uncovered
line found four defects, now fixed. Certification is recorded in #75.
Distribution is R-universe until CRAN accepts the submission. The joint 1.0.0
release with contentvalidR is tracked in #53.
CRAN preparation for the first submission (#39).
DESCRIPTION declares Language: en-US, and the package's text uses American spelling throughout. About 40 British spellings (analysed, modelled, behaviour) are changed in messages, help pages, articles, and NEWS; only wording changes, not code. spelling::spell_check_package() now finds nothing, with author names and technical terms listed in inst/WORDLIST.urlchecker::url_check() finds all 131 URLs correct..git and .gitignore are excluded from the build. A git worktree has a .git file, and a hidden file in the tarball is what CRAN returned contentvalidR 0.3.1 for.nomo_scores() and nomo_apa_table() gain runnable examples, so every exported function now has one.DESCRIPTION cites the two works that frame the package, Cronbach and Meehl (1955) and Flake, Pek, and Hehman (2017), with their DOIs.?nomo_apa_table already cited. Its "Planned" notes now say that longitudinal invariance and multiple imputation are candidates for v0.4, not v0.3.nomo_report(apa_tables = TRUE) appends a Manuscript tables appendix (#73, last of three parts). It holds the nomo_apa_table() tables for the results a run holds: CFA loadings, fit, and factor correlations; reliability; and, when present, invariance and the network's hypotheses and fit. They are numbered in the order the report presents them. A table that does not apply is left out rather than failing the report. The default, FALSE, leaves reports unchanged.
nomo_run() can score the measurement model and compare missing-data strategies, and its report shows both (#73, second of three parts).
settings = list(scores = list(method = "sum")) scores the model with nomo_scores(). The researcher must name the method; a request without one, including scores = list(), is refused, because nomologR does not choose a scoring method.settings = list(missing = list()) compares strategies with nomo_missing() for the measurement model, and for the network too when one is requested.A written stability and deprecation policy, on the package help page (?nomologR) and in the README (#74). From 0.3.0, the first CRAN release, the public interface changes only after a deprecation period.
nomo_table() types, and decision-log columns.nomo_missing(), whose flagging rule may be refined, and the layout of nomo_apa_table() tables. Both are marked in their help pages.contentvalidR.nomo_run() computes careless-responding indices when settings = list(screen = list(effort = TRUE)) is given (#73, first of three parts).
nomo_screen(effort = TRUE) call exactly.reverse, scale_range, pair_magnitude, and scales can be set alongside effort. When the scales came from a contentvalidR handoff that declares keying, that keying is used unless the settings give their own, and the design log records which applied.effort value is refused before any stage runs.nomo_screen() and nomo_run() accept a handoff from contentvalidR's content_handoff(), so items move from content review to empirical screening with their reasons intact (#46). The interface is schema version 1, agreed with the contentvalidR maintainer and documented identically in both packages.
nomo_screen(data, items = handoff) screens only the items content review carried. Every held-back item is listed in the decision log with its status and recommendation quoted in contentvalidR's own words, and is never analyzed or reinstated.nomo_run(data, scales = handoff) takes its scales from the review, and its design log records that item membership came from content review rather than from these data. A review with no construct mapping, such as an expert relevance panel, is refused by nomo_run() with the carried items listed, because a guided run needs scales and nomologR does not invent them. It can still be screened.reverse and scale_range for the careless-responding indices, exactly as agreed. An undeclared item is never treated as forward keyed, a response scale is never inferred from the data, and arguments given in the call take precedence, with a note in the log.contentvalidR can add fields within a schema version. An object content_handoff() could not have produced, such as keying missing for some items but not others, is refused as malformed.nomo_report() gains a content-review section for runs that came from a handoff, so the archive starts where the validity argument starts. Reports of other runs are unchanged.contentvalidR is not a dependency. The reader is tested against genuine output from contentvalidR 0.6.0 and 0.7.0, stored in tests/testthat/fixtures with their generator and checksums. The guided-workflow article gains a runnable section built on the example handoff in inst/extdata.The research-basis article describes the careless-responding indices that shipped in 0.2.1. It had still listed them as planned.
Test coverage is back to full executable-line coverage after v0.2.1 (#72). Reviewing each uncovered line found four defects, now fixed:
nomo_missing(). For a nomo_network, the fit comparison listed every fit index as missing. A network's fit evidence is one wide row, while a CFA's is a long table, and only the long form was read. Every strategy's chi-square, CFI, TLI, RMSEA, and SRMR now appear.nomo_scores() with ordered indicators. The parallel-model test that unit weighting implies was written for continuous indicators. With ordered indicators it was fitted by maximum likelihood against a categorical model, failed, and reported only that the comparison "could not be computed". It is now not run for ordered indicators, and the note says why.nomo_network had an "RMSEA [90% CI]" column but printed no interval. The interval is now read from the fit, using the robust, scaled, or plain RMSEA that the evidence reports.NaN when no scale had two items. It now returns NA, as the inter-item SD already did.Lines that no input can reach were removed rather than tested. Examples are the empty-row checks in the careless-responding indices and the guards for fitted models that are always present. The remaining guards are tested against real fitted objects:
Failures that only lavaan can produce are simulated.
nomologR 0.2.1 completes the six workstreams that moved out of v0.2.0 at certification (#37). It also carries three workstreams opened during the cycle (#54, #56, #62). Together they cover what happens after a measurement model is established:
Where a published worked example exists, the package reproduces it exactly: Curran's (2016) examples for the careless-responding indices, and Rodriguez, Reise, and Haviland's (2016) MASC values for factor determinacy and construct replicability. Skrondal and Laake's (2001) factor-score regression design and the missing-data comparison are checked against known population values. Every source cited is in the research-basis reference list, with its DOI checked against the registry. Certification is recorded in #70. Distribution remains R-universe; the first CRAN submission is targeted for v0.3.0 (#39).
nomo_report() now works from inside a knitted R Markdown or Quarto
document, such as a thesis chapter, with no workaround in the calling
document (#40). A nested render shares knitr's state with the document that
started it, which previously stopped the report with a duplicate chunk label,
and which silently dropped every figure from the report when the calling
document set a graphics device its template did not expect. The report is now
rendered with knitr's default chunk options, which its own template then sets
for itself, and the calling document's chunk options and duplicate-label
setting are restored afterwards. A report therefore renders the same from the
console, a script, or a chunk, and rendering one does not change the document
that asked for it.
Restored full executable-line coverage by testing every nomo_compare()
failure guard (#54). These branches handle a failure inside lavaan or
semTools rather than a researcher-facing input, and several of them produce
the explanation a researcher reads when a check cannot be run, such as why a
nesting check was skipped or why a difference test is unavailable. Wording
that has never executed can be wrong without anyone noticing, so those
sentences are now asserted against real fitted objects.
nomo_hierarchical() now reports factor determinacy and construct
replicability for the general factor and each group factor, in a new
factors table reachable with nomo_table(x, "factors") (#56). Both
reproduce the published values for the MASC example in Rodriguez, Reise, and
Haviland (2016) exactly. The two indices are the same quantity only when a
construct is unidimensional: under a bifactor model, determinacy uses the
whole reproduced correlation matrix while H sees one factor's loadings alone,
and Rodriguez et al. decline to prefer either, so both are reported and each
is labeled with the question it answers. Gorsuch's (1983) and Hancock and
Mueller's (2001) thresholds appear as their authors' recommendations where a
value falls below them, never as rules.
Added nomo_scores(), which computes sum, mean, regression, or Bartlett
scores from a fitted measurement model and reports what those scores are and
are not (#33). Unit weighting is treated as the model it is: McNeish and Wolf
(2020) show that adding items assumes a parallel model, with equal
unstandardized loadings and equal residual variances, so for "sum" and
"mean" that constrained model is fitted and compared with the model
supplied. Every method reports Grice's (2001) three criteria, computed from
the fitted model: validity, univocality, and correlational accuracy. Validity
for regression scores is the factor determinacy coefficient reported by
nomo_hierarchical(), since that method maximizes it. Correlational accuracy
is the one to read before using scores in a later analysis: correlations among
scores do not reproduce correlations among the factors, the discrepancy is
substantial, and its direction depends on the method and the model rather than
being a constant that could be corrected for, so it is reported and left
visible. Gorsuch's (1983) thresholds appear as his recommendations where a
value falls below them, never as rules. The supplied data is never modified,
and only the cases the model used are scored. Includes the Scoring a
measurement model article.
nomo_screen() gains effort = TRUE, which adds case-level indices of
careless or insufficient-effort responding (#34): long-string, inter-item
standard deviation, Mahalanobis distance, even-odd consistency, and
psychometric antonym and synonym correlations, following Meade and Craig
(2012), Huang et al. (2012), Curran (2016), and Marjanovic et al. (2015).
Curran's published worked examples are reproduced exactly and used as tests.
The indices are reported side by side rather than combined, because they
detect different failures: inter-item standard deviation detects random
responding and gives a respondent who answers every item identically the best
possible score, which is exactly the case long-string flags. The decision log
reports that disagreement when it occurs. A case is flagged only where a
source states a rule, with the source's own qualification attached; the rest
are reported without a flag. Inter-item standard deviation is averaged within
scales, as Marjanovic et al. computed it, since one value across every item
rates a respondent who is high on one construct and low on another as more
erratic than a random responder. Within-person correlations over fewer than
three pairs or scales are never reported, because with two every value is
exactly +1 or -1. Reverse keying and the response range are declared, never
inferred, and recoding happens on an internal copy only. Cases are flagged,
never removed, and a screen that does not request these indices is unchanged.
nomo_table() now supports nomo_screen objects.
nomo_network() now discloses relationships estimated between observed
variables (#62). When an endpoint is observed rather than latent, its
measurement error enters unmodeled, and if it is a composite of several items
(a sum, mean, or factor score) the relationship carries the discrepancy
nomo_scores() reports as correlational accuracy. The network cannot tell a
composite from a single measured variable, so it does not guess: it classifies
each hypothesis by its endpoints and discloses observed ones in the decision
log, for review when both ends are observed and for information when one is,
saying plainly that a single measured variable is not a composite. The
disclosure points to modeling the items as indicators, to lavaan::sam()
(Rosseel & Loh, 2024), and, for a linear regression among factor scores, to
the design Skrondal and Laake (2001) proved consistent: regression-method
scores for the predictors and Bartlett scores for the outcome, each block
scored from a measurement model of its own. The second condition is easy to
miss. In reproducing their result, scoring both factors from one joint model
biased the estimate by about +.10 in the same check that recovered the latent
value with separate models. No correction is applied automatically.
nomo_scores() and the scoring article now describe that design (#62). The
note on correlational accuracy says that scores from one model containing
every factor are not it, and the article applies it to its own data next to
the two ways of getting it wrong: the same method for both blocks falls well
short of the latent slope, and scoring both factors jointly overshoots it.
nomo_reliability() gains ci_ncpus, which runs the bootstrap on several
worker processes through lavaan's snow backend (#42). The default, 1, keeps
the bootstrap serial and unchanged. snow is used everywhere rather than
forking, which is unavailable on Windows, so results are comparable across
platforms. The draws depend on the worker count as well as the seed, so a
result is reproducible for a given seed and worker count: both are recorded in
the bootstrap status table and, newly, in the decision log that reaches
reports, which previously carried neither. An unseeded bootstrap is flagged
for review as not reproducible. Verified against an installed package: the
same seed and worker count give identical intervals, and serial and two-worker
runs differ by under .01, as the draws should. More workers are not always
faster, since each must start and load its packages; in the evaluation
recorded on the issue, eight workers were slower than four. Tests use at most
two workers, following CRAN policy.
Added nomo_apa_table(), which formats the evidence in a result as an APA 7
table ready for a thesis, dissertation, or manuscript (#35): standardized
loadings, factor correlations, and model fit from nomo_cfa(); reliability
from nomo_reliability(); the invariance sequence from nomo_invariance();
and hypothesis evidence and model fit from nomo_network(). Tables carry a
bold number, an italic title, no vertical rules, and notes below in APA's
order, and they knit directly into R Markdown or Quarto. Leading zeros follow
the statistic rather than its value, as APA 7 specifies: statistics that
cannot exceed 1 (reliability, correlations, CFI, p) lose the zero, and those
that can (TLI, RMSEA, SRMR, standardized loadings) keep it. A value that rounds
to zero is never printed with a sign, and an estimate the model could not
produce is shown as an em dash. The hypotheses table reports each estimate's
evidence against its prediction, and marks a hypothesis specified after the
data were seen as exploratory. No cell reads pass or fail. Word output for
nomo_report() follows separately.
nomo_report() now writes Word documents: a file ending in .docx
produces one, alongside the existing HTML report (#35). Pandoc drops raw HTML
when it writes Word, and the report template wrote its tables, notes, and its
interpretation contract as raw HTML, so a Word report would have lost all of
them, including the statement that the report does not turn review references
into pass/fail rules. Each part of the template now writes HTML for an HTML
report and markdown for a Word one, and the HTML report is unchanged. The Word
report was checked against the HTML one: the same 37 data tables with the same
header rows in the same order, the interpretation contract, the figures, and
no raw HTML or escaped entities in its text. Collapsible sections are shown
expanded, and the document uses Word's default styles. Section numbering is
used where the installed rmarkdown supports it for Word.
Added nomo_missing(), which refits a nomo_cfa or nomo_network under
alternative missing-data strategies and reports whether the cases used, the
estimates, fit, reliability, or theory evidence change (#32).
nomo_demo_continuous, whose missing values are MCAR by
construction, and to a simulated MAR sample.nomologR 0.2.0 makes the workflow research-backed from historical to contemporary practice and more useful to graduate students and researchers. Every method is placed in its literature and cited in reports; researchers can compare competing models, revise a model with its lineage recorded, and evaluate total and subscale scores; and replication language no longer reads noise as a finding. Scope was selected in #22.
Six Planned workstreams moved to v0.2.1 at release certification (#37), each with its reason recorded: missing-data sensitivity (#32), score guidance (#33), insufficient-effort responding screens (#34), manuscript-ready tables (#35), rendering reports inside R Markdown or Quarto (#40), and optional parallel bootstrap intervals (#42). The license is GPL-3.0-only; the published 0.1.0 release keeps its original MIT license. Distribution remains R-universe; the first CRAN submission is targeted for v0.3.0 (#39).
ROADMAP.md,
LICENSE.md) now use absolute URLs, so they resolve for readers of the
package tarball as well as on GitHub (#48).nomo_compare() example now skips the
side-by-side evidence, which moved to \donttest{}, keeping every
default-run example within CRAN's time expectations.nomo_methods() crediting rule against real
objects found, and fixed, methods that reports would have mis-cited: WLSMV
comparisons were credited with the Satorra-Bentler scaled test instead of the
scaled-and-shifted test; AIC and BIC were never credited; FIML requested as
missing = "ml" or "direct" was not credited; a requested Fornell-Larcker
comparison was not credited; and a nomo_partial() release specification was
credited with a multiple-group fit it does not perform. A registry entry for a
fixed change-in-CFI rule that no function displays was removed.nomo_revise() now refuses an item revision whose measurement model
disagrees with the revised items. Previously, dropping an item without
supplying a revised cfa_model screened and explored the reduced item set
but still fitted the dropped item in the CFA, while the lineage recorded it as
removed.nomo_model() gains structure = c("correlated", "higher_order", "bifactor") and general. Bifactor syntax writes its identification and
orthogonality explicitly, so it is identified the same way whatever std.lv
is used. Higher-order models need at least three first-order factors; with
exactly three the model is noted as fitting exactly as well as correlated
factors. Impossible configurations are refused and fragile ones noted.nomo_hierarchical(), which reads a fitted bifactor or higher-order
model and reports omega total, omega hierarchical, their ratio, explained
common variance (ECV), the percentage of uncontaminated correlations (PUC),
and, per subscale, omega and omega hierarchical subscale, with item-level
general and group loadings. For higher-order models these are the exact
Schmid-Leiman decomposition.semTools::compRelSEM() under
both observed and model-implied denominators. Ordered indicators report the
latent-response estimand, labeled as an upper bound on observed ordinal
sum-score reliability.nomo_reliability() and nomo_validity(),
and nomo_reliability()'s cross-loading refusal, now point to
nomo_hierarchical().print(), summary(), plot(), and nomo_table() methods, seven
methods-registry entries, and the Total and subscale scores article."sign_reversal" from the point estimates alone. Estimates scattered
around a null relation differ in sign about half the time, and the previous
label called that "a substantively important replication discrepancy.""sign_reversal" when both exclude zero on
opposite sides, "direction_not_replicated" when exactly one excludes zero,
and "sign_change_within_uncertainty" when neither does or an interval is
unavailable. The first two are recorded as concerns and the third for review.?nomo_network, the
nomological-network vignette, and the research-basis article. It does not
treat a non-significant path as evidence of no relation; that still requires
a negligible(within = ...) prediction.nomo_methods(), a machine-readable registry of every method the
package implements. Each entry records its workflow stage; its lineage
(historical, contemporary, or emerging); its role (primary,
supporting, or context); its estimand and key assumptions; the function
and computational engine that implement it; and its references.role = "context" marks methods displayed only so readers can recognize them
in published work, such as the eigenvalue-greater-than-one rule and fixed
fit-index cutoffs. They take no part in any synthesis or decision.nomo_methods(x) returns only the methods a result object actually used,
read from what each component recorded: a skipped retention criterion, alpha
that was not computed, or a comparison that was not run is not credited. A
one-factor solution is credited with no rotation method, since none was
applied.references = TRUE expands the result into a reference list with full
citations and DOIs.nomo_report() now lists the methods
the run used and a deduplicated reference list for them, ahead of the
software citations it already contained. summary() of a nomo_run and
nomo_table(run, "methods") show the same methods.dev/verify-method-dois.R resolves
each DOI and checks that the registered first author, year, and title match
the citation; all 79 DOIs pass.nomo_revise(), which creates a child workflow from a parent
nomo_run() with a revised measurement model, a revised item set, or both.
The parent workflow is never modified.nomo_compare()
(#27), so a revision carries its own evidence. Item changes alter the
observed variables, so those comparisons are descriptive, as documented.$lineage accumulates one row per revision and is available
through nomo_table(run, "lineage"), in print() output, and in a new
"Revision lineage" section of nomo_report().measurement_model = "revise" decision now points to nomo_revise()
instead of only advising a fresh workflow.nomo_compare() for comparing two or more fitted nomo_cfa() models.
A researcher rationale is required and recorded, the comparison can be
labeled a priori or post hoc, and no model is ever selected automatically.lavaan::lavTestLRT(): the ordinary chi-square difference test
for ML, the scaled difference test for robust ML (Satorra & Bentler, 2001),
and the scaled-and-shifted test for WLSMV (Satorra, 2000). A test lavaan
cannot compute, or a negative scaled statistic, is reported as unavailable
with lavaan's message rather than replaced by another method.semTools::net()
(Bentler & Satorra, 2010). Researchers can declare nesting when the check
cannot run, and a declaration the check contradicts is recorded as a concern.print(), summary(), plot(), and nomo_table() methods.R/nomo_run.R, 2,066 lines) into
nomo_run_state.R (state and input validation), nomo_run_decisions.R
(researcher decisions), nomo_run_stages.R (stage execution and blocking),
nomo_run_provenance.R (provenance, recipe, and settings tables), and
nomo_run.R (entry point). Every function body and signature is unchanged,
verified by comparing the parsed functions with the previous source, and the
generated documentation is identical.tests/testthat/test-regressions.R, which were
consolidated during pre-v0.1 hardening, into the per-module test files. Test
names, the number of tests (464), and expectation calls are unchanged.EFAtools from 0.8.0 to 1.0.0. With
EFAtools 0.8.0, nomo_factors() could not run the empirical Kaiser
criterion, NEST, Hull, or comparison-data criteria, and 22 factor-retention
tests failed. The full test suite passes with the declared minimums
lavaan 0.6-21, semTools 0.5-9, and EFAtools 1.0.0.DESCRIPTION
Imports, confirms they are the versions installed, and runs R CMD check,
so a declared minimum is never an untested promise.snow
workers were about 3.5 times faster than serial refitting, and results are
reproducible for a given seed and worker count but differ across worker
counts. Because an opt-in option adds a user-facing argument and provenance
fields, it is tracked separately (#42); bootstrap behavior is unchanged here.v0.2.x, a
CRAN-readiness gate in v0.2.0 certification (#37), and the first CRAN
submission targeted for v0.3.0 (#39).v0.2.0 direction: research-backed, usable scale-development and
construct-validation workflows for graduate students and researchers,
spanning historical to contemporary methods. Scope, priorities, and exit
criteria were recorded in #22 and the linked workstream issues (#25–#37);
v0.3 candidates are tracked in #38. Distribution remains R-universe; CRAN
submission is deferred (#39).data-raw/nomo_demo.R:
nomo_demo_continuous (two correlated factors with a cross-loading item, a
weak item, and MCAR missingness), nomo_demo_ordinal (five-category ordered
version), and nomo_demo_network (three constructs, an observed outcome, and
two administration groups with a known source of scalar non-invariance)
(#25).\dontrun{} examples with runnable examples and added examples to
nomo_network(), nomo_invariance(), nomo_table(), and nomo_defaults()
(#25).nomo_table(<nomo_invariance>, "local_strain") now adds a
constraint_display column with human-readable parameter labels (for
example Intercept: ag3 (online vs. paper)); the raw lavaan constraint
label is retained (#31). No statistical behavior changed.pdf() device these
symbols were dropped or mangled, and running the vignette code under
R CMD check failed. Labels now read Delta CFI, Delta RMSEA,
Delta SRMR, ->, and <->, matching the hypothesis syntax.nomo_table().dev/roadmap-v0.1-record.md and refocused ROADMAP.md on v0.2 and later.GPL-3.0-only; GPL-3 in R metadata), retaining the historical MIT notice.
Previously published releases retain their original licenses.0.1.0.9000;
release tags retain their release-specific citation metadata.v0.2.0.v0.1.0 remains the current stable public release.nomo_report() as the archival reporting layer for guided
nomo_run() workflows.covr::zero_coverage() result.v0.1.0 as the first stable public release after release-readiness review and certification.nomo_run() development stub with a resumable guided workflow
spanning screening, factor-retention evidence, EFA, CFA, reliability,
convergent/discriminant evidence, optional invariance, and optional
theory-specified nomological-network analysis.nomo_split-aware sample roles and exact-model network replication.R/nomo_run.R; the full test suite and R CMD check were clean.positive(), negative(), and negligible() expectation helpers plus
nomo_hypotheses() for machine-readable a-priori and post-hoc theory
specifications. Quantified negligible predictions use researcher-specified
SESOI/equivalence regions; bare negligible predictions remain qualitative and
are never confirmed merely because p > .05.nomo_network() for theory-specified latent SEM with transparent
addition of missing prespecified theory paths, observed external
criteria/outcomes, standardized or explicitly unstandardized hypothesis
evaluation, measurement-context propagation, and calibration/validation
replication of the exact same prespecified fitted model.nomo_invariance() using current semTools::measEq.syntax() and
lavaan infrastructure with identification-aware sequences for continuous,
ordered 4+ category, three-category, and binary indicators.nomo_partial() for explicitly researcher-specified partial-invariance
releases with required rationale and cumulative provenance. The package never
searches until it finds a partial-invariance model that passes.nomo_table() methods plus researcher-facing network and invariance
figures, including theory-compatible regions, replication comparison,
fit/change evidence, and human-readable localized equality constraints.R/nomo_hypotheses.R 94.33%, R/nomo_network.R 89.95%,
R/nomo_network_presentation.R 91.49%, R/nomo_invariance.R 92.04%,
R/nomo_invariance_presentation.R 93.27%, R/nomo_partial.R 90.57%, and
R/nomo_table.R 100.00%.0.1.0.9003, marking Checkpoint C:
Generalizability and Nomological Evidence Complete. Milestone 8,
nomo_run(), is the next active development target.nomo_reliability() development stub with a model-based
reliability workflow using current semTools::compRelSEM() infrastructure.nomo_validity() development stub with convergent and
construct-separation evidence including standardized loadings, AVE, latent
correlations, HTMT2, original HTMT, and optional legacy/supporting
Fornell-Larcker output.print()/summary() methods and nonredundant reliability, AVE,
and construct-separation plots. Coefficient plots use the conceptual 0-to-1
scale by default and expand only when empirical estimates or intervals require
it.semTools::compRelSEM(),
semTools::AVE(), and semTools::htmt(), plus ordinal, redundant-construct,
weak-measurement, bootstrap-uncertainty, failure-disclosure, and presentation
hardening tests.R/nomo_reliability.R 90.26%, R/nomo_validity.R 92.56%,
R/nomo_measurement_helpers.R 92.70%,
R/nomo_reliability_uncertainty.R 89.33%,
R/nomo_reliability_presentation.R 88.93%, and
R/nomo_validity_presentation.R 81.20%.
Coverage hardening targeted consequential branches rather than artificial
100% execution of low-value presentation/failure paths.0.1.0.9002, marking Checkpoint B:
Measurement Model Complete. Milestone 6, theory-specified nomological
networks, is next.nomo_cfa() development stub with a production CFA workflow
around lavaan::cfa() while retaining the underlying lavaan fit unchanged.nomo_model() for simple reflective CFA syntax generation without
automatically adding cross-loadings, residual covariances, or other post-hoc
parameters.print(), summary(), and four CFA plot views for standardized
loadings, global fit, localized residuals, and modification indices.nomo_split() for reproducible calibration/validation splitting,
including the independence-versus-precision tradeoff and restoration of the
caller RNG state.lavaan::cfa() plus stress tests for
correctly specified and misspecified CFA, omitted cross-loading, omitted
correlated residual, ordinal CFA, robust ML, FIML, nonconvergence, improper
solutions, modification-index quarantine, and split-sample reproducibility.R/nomo_cfa.R 97.37%, R/nomo_cfa_presentation.R 99.58%,
R/nomo_model.R 97.73%, and R/nomo_split.R 98.31%.nomo_efa() development stub with a production common-factor EFA
workflow using psych::fa() as the statistical engine and nomologR as the
guidance, diagnostics, logging, and presentation layer.nomo_factors(), including inherited item sets, modeling types, correlation
models, missing-data decisions, and explicit smoothing choices.KEEP, REVIEW, and STRONG REVIEW item guidance based on configurable
loading, cross-loading, and communality teaching references without automatic
deletion, reverse scoring, factor-count changes, rotation hunting, or hidden
model refitting.F1, F2, ...) while retaining the full
underlying psych fit object for advanced inspection.summary.nomo_efa() and four teaching-oriented plot views for pattern
loadings, primary/secondary loadings, unique residual pairs, and unique
interfactor correlations.nomo_factors() object are distinguished from new researcher overrides made
at the EFA stage.nomo_screen() -> nomo_factors() -> nomo_efa().R/nomo_efa.R, 98.70% for
R/nomo_efa_presentation.R, and 96.52% package-wide in the final pre-closeout
audit.0.1.0.9001, marking Checkpoint A:
the exploratory measurement workflow is complete and Milestone 4 (CFA) is next.types
declaration can rescue otherwise ambiguous storage before default-type
rejection, while storage-compatibility checks still block unsafe coercions.types,
including ordered interpretation of factor levels and the limits of overrides.correlation and modeling_types fields alongside the
existing internal-detail names for easier inspection of automatic choices.nomo_factors() from a two-criterion workflow into configurable
retention bundles: minimal, core, extended, and all.core bundle.all bundle; the legacy rule is excluded
from the evidence synthesis.plot.nomo_factors() with parallel-rule sensitivity, MAP curves,
multi-method evidence, and retention-concordance views.EFAtools (>= 0.8.0) as the runtime engine for modern optional retention
criteria while preserving nomologR's interpretation and decision-log layer.nomo_factors() development stub with a production factor-retention engine.summary.nomo_factors() and plot.nomo_factors() views for retention,
scree, method-concordance, and KMO evidence.psych to a runtime dependency because factor-retention methods now
use its established factor/correlation engines directly.summary.nomo_screen() with an integrated item-review table that
combines descriptive, relationship, response-category, and decision-log evidence.plot.nomo_screen() with evidence-map, item-rest, inter-item,
response-profile, and missingness views.none, review, concern) that
remains deliberately non-prescriptive about item retention.ggplot2 as a core visualization dependency and expanded regression
tests for presentation behavior.nomo_screen() printing and tests for the psychometric screening layer.contentvalidR -> nomologR measurement workflow
and the active v0.1 development path.nomo_screen().print.nomo_screen() method.actions/checkout@v5 for the Node 24
runtime.nomologR as a guided workflow for empirical scale development and
construct-validity evidence rather than a replacement for psych, lavaan,
or semTools.contentvalidR and solomonR.nomo_* prefix.semTools infrastructure such
as compRelSEM().semTools
infrastructure such as measEq.syntax().