A patch release. It fixes a bug in the participant-level permutation
test of perm_solomon() that made p-values too small when permutations
tie with the observed statistic (#131). Rerun perm_solomon() for
outcomes with tied scores (binary outcomes, counts, ratings, rounded
scores) and for very small groups. No other function changes from 0.8.1.
At the participant level, perm_solomon() let rounding error decide
whether a permutation whose statistic equals the observed one was
counted as at least as extreme. The validity of the p-value is shown for
the count of statistics at least as extreme as the observed one (Phipson
& Smyth, 2010), so such ties must be counted; when they were missed, the
p-value was too small. They are now counted, at the participant and the
cluster level and in plot_perm(), by one rule: statistics that differ
by less than a small relative tolerance are equal. At the participant
level the tolerance is 1e-10 for a linear model and 1e-6 for models
fitted by iteration. At the cluster level, where the model is not
refitted for each allocation, it is 1e-10 for every model.
Also in perm_solomon(): the refitted models may take up to 200
iterations where they took 25, which removes convergence warnings that
some models gave.
What remains (#134):
What can change: p-values that were too small. Rerun perm_solomon()
for analyses of these kinds.
With continuous scores and 10 or more participants per group a tie is
rare. For a contrast within one pretest condition, about 1 analysis in
100 with 999 permutations meets one, and its p-value rises by at most
.001; for the average treatment effect and Pretest x Treatment, almost
none does. The scores of solomon_example are whole numbers, so its
own p-values change slightly: in one run of 4,999 permutations for
Treatment | unpretested, from .102 to .105.
An observed statistic of exactly zero now gives a p-value of 1, when the outcome varies within the pretest conditions the contrast uses. Rounding could give less: with 2 of 5 successes in each arm, one test gave .67.
Cluster-level tests give the same results as before, with one exception: an observed statistic of exactly zero now gives a p-value of 1 there too. Rounding could give less: with 3 treated and 3 control clusters, whose 20 allocations are all used, one test gave .9.
A patch release. It fixes a bug in 0.8.0 that gave wrong contrasts in
fit_solomon_sem() and fit_solomon_sem_latent() when the data did not
begin with a pretested, treated participant (#119): refit any such
analysis. It also includes the documentation, attribution, and
CRAN-readiness changes made since 0.8.0.
fit_solomon_sem() and fit_solomon_sem_latent() gave wrong contrasts
when the data did not begin with a pretested, treated participant. Their
models label the four group means by position, and lavaan orders groups
by their first appearance in the data, so with other row orders the
labels were attached to the wrong groups: on solomon_example with an
unpretested control first, the average treatment effect came out as
-2.68 instead of 2.68. The group order is now fixed. Results from data
that began with a pretested, treated participant, including every
example in the documentation, are unchanged.std_lv documentation of fit_solomon_sem_latent() now says that
the latent variance is fixed at 1 in the pretested treatment group, so
latent contrasts are in that group's latent SD units.fit_solomon_steyn() are now credited to
Scheffé (1953), whose method they are, as well as to Steyn (2005), who
used them, and report_solomon() cites both. The help page states
Scheffé's criterion, its equivalence with the F test, and his advice to
prefer Tukey's method when only pairs of equally precise means are
compared. It no longer says, without a source, that Holm's adjustment is
less conservative for pairwise comparisons.?steyn2005 cites Steyn and Mynhardt (2008), the English report of the
eight-group study: its account of the assignment, its 2 x 2 results, and
where they differ from the thesis.?fit_solomon_steyn notes that Steyn (2009) credits the E1 and E2
comparisons for one intervention to Steyn (2001).cran-comments.md records the check results for the eventual CRAN
submission. Nothing has been submitted.This release brings together the work planned for v0.5.0 through v0.8.0, and the stable interface (#83) and the first CRAN-readiness changes (#84) planned for v0.9.0. Versions 0.5.0, 0.6.0, and 0.7.0 were not released separately.
fit_solomon_glm() now analyzes Solomon N-group designs: k treatments and
a control, each with and without a pretest, giving 2(k + 1) groups (Steyn,
2009). Give treat as a factor or character vector and name the control
with the new control argument.
contrasts = "pairwise"), or
for planned comparisons given as weights, such as the main effects of a
factorial design.adjust).solomon_ngroup. Results for four-group designs
are unchanged, and a two-condition factor with control gives the same
fit as a 0/1 treat.fit_solomon_steyn() carries out the sequence of tests Steyn (2009)
proposed for designs with one or several treatments: checks of
equivalence, history and maturation, testing, the pretest-intervention
interaction, reliability, regression to the mean, and attrition, then
tests of the treatments' effects. Its post
hoc tests are Scheffé tests, as in Steyn (2005), or Holm-adjusted pairwise
t tests (posthoc). It is a published proposal, kept for replication and
teaching. It follows a pre-publication draft of the article, dated March
2, 2009, which the author provided (R. Steyn, personal communication,
September 30, 2026); the published article was not available for
comparison.steyn2005: the group statistics of Steyn's (2005)
eight-group study, which reproduce its published analyses of variance and
Scheffé tests.validate_solomon(), check_solomon_missing(),
check_solomon_assumptions(), and baseline_solomon(), with control;plot_solomon_design() (also treatments, for a schematic without
data), plot_solomon_means(), and plot_solomon_change(), with
control, and plot_sensitization() and plot_solomon_effects(), for
an N-group fit;equivalence_solomon(), with the new comparison argument;report_solomon(), for N-group fits and for fit_solomon_steyn()
results;simulate_solomon(), with one delta (and sens) per treatment;solomon_from_summary(), with treat, pretested, and control.solomonR_ngroup_unsupported, that says how to
proceed. power_solomon() and plan_solomon() give a clear error for
more than one delta or sens.plot_sensitization() now works for clustered (CR2) fits with an
exposure offset.data, a bare column name is now always read as that column, even
when the column's values are themselves names of columns.fit_solomon_mmrm() analyzes a Solomon design with several posttest
occasions by a mixed model for repeated measures, following Mallinckrodt
et al. (2008): occasion by treatment by pretesting, the pretest adjustment
of fit_solomon_glm() with a slope at each occasion, and an unstructured
covariance by REML (Laird & Ware, 1982), estimated separately for
pretested and unpretested participants. It reports the four Solomon
contrasts at each occasion and the change in sensitization, with
Kenward-Roger or Satterthwaite degrees of freedom, and falls back to
other covariance structures by AIC if the unstructured model does not
converge. It needs the mmrm package (Sabanes Bove et al., 2026), now a
suggested dependency.report_solomon() reports it.analysis_plan_solomon() gains occasions and primary_occasion. With
several posttest occasions, the plan's primary analysis is
fit_solomon_mmrm(), its confirmatory contrasts are those at the primary
occasion, and its missing-data section states the assumption about
dropout. The tipping-point analysis is not offered there, because it
imputes from the pretest alone.jordaan2014: the group statistics of Jordaan's (2014)
randomized Solomon study with three posttest occasions, on the three
subscales of the Coping Strategy Indicator. They reproduce the 27 F
values of the thesis's nine analyses of variance, one per subscale and
occasion.jordaan2014 with solomon_from_summary() and
fit_solomon_mmrm(). It also shows that a change in sensitization across
occasions cannot be judged from group statistics alone: for social
support, the drop in the Pretest x Treatment interaction from the
posttest to 6 months has p = .149 if the correlation between occasions
is 0.2 and p = .005 if it is 0.8.analysis_plan_solomon() writes an editable Markdown analysis plan
for a new Solomon study, for preregistration or a protocol.
plan_solomon() result, which now keeps its planning values in a
settings attribute.report_solomon(design = list(plan = )) states from the plan whether the
sensitization analysis was pre-specified, and names the plan's date and
confirmatory contrasts.rmarkdown::draft("study.Rmd", "solomon-study", package = "solomonR")),
runs a planned analysis in order, from the design check to the report.analysis_plan_solomon() is experimental until researchers have used it.fit_solomon_mi() multiply imputes missing posttests and combines
the four Solomon contrasts with Rubin's rules (Carpenter et al., 2023).
delta shifts the imputed posttests of each group by a
fixed amount: the delta-adjusted pattern-mixture analysis of Carpenter
et al. (2023, section 10.3), with offsets per group as in Little et al.
(2012). Offsets that differ between the pretested and unpretested groups
bear on the sensitization contrast.m = 100).tipping_point_solomon() repeats the analysis over a range of
offsets and reports where each contrast's conclusion changes, as White et
al. (2011) recommend. plot_tipping_point() draws it.report_solomon() reports both, with their references.plot_tipping_point(), stay
experimental. The analyses that assume missing at random biased the
sensitization contrast by 0.10 to 0.16 SD when the departure was
confined to one pretested group.fit_solomon_mi() and tipping_point_solomon() say
that with much missing information, 100 imputations can leave the
p-values and the tipping point varying from seed to seed, and give a
locator for their quotations of White et al. (2011).report_solomon() and tools/check-references.R now
compares the first author's surname and initials before the other
authors, so that "Little, R. J." precedes "Little, R. J. A.".The public interface is now settled. Former names keep working, with a deprecation warning, through v1.x, when the arguments that follow a former argument name are also named.
fit_solomon_glm() takes y_post and y_pre (formerly y and
pretest_score), and fisher_solomon() takes y_post (formerly y),
as every other function does.fit: equivalence_solomon() and
perm_solomon() formerly took object. plot_solomon_design() takes
y_post or fit (formerly x), and a fit passed by position still
works.fit_solomon_classic()'s combine_with_stouffer is now stouffer, as
in power_solomon().power_solomon() now takes
n, delta, sens, rho, sigma, and alpha in that order, as
plan_solomon() and plot_power_solomon() do. Formerly rho came
before sens, and alpha came after sims and stouffer, so a call
that passes these by position gets a warning that it was read in the new
order.data argument. Every function that takes data vectors also takes
an optional data frame, data, whose columns can be named bare or as
strings, for example fit_solomon_glm(post, group, took_pretest, pre, data = mydata). With data, covariates can be a vector of column
names.plot_solomon_means() draws the four posttest
means with t intervals in ggplot2, as the other plots do, and takes
conf_level. plot_solomon() (base graphics) and plot_solomon_gg()
are deprecated.fit_solomon_sem(),
fit_solomon_sem_latent(), invariance_solomon(), fit_solomon_mmrm(),
fit_solomon_mi(), tipping_point_solomon(), plot_tipping_point(),
and analysis_plan_solomon(), with the analysis of several treatments
in fit_solomon_glm(); ?solomonR gives the reasons.fit_solomon_glm(), fit_solomon_classic(), fit_solomon_ml(),
perm_solomon(), fit_solomon_sem(), check_solomon_assumptions(),
p_to_z(), and plot_perm() now have runnable examples on their help
pages. Each runs in under 3 seconds.fit_solomon_sem() now documents its return value.tools/check-references.R now fails if a work on the Solomon design is
in the bibliography without a coverage entry.fit_solomon_classic() and
fit_solomon_1949() now credit him.lana1959 holds the posttest statistics of Lana's (1959) attitude
experiment, one of the first built on the Solomon design.
solomon_from_summary() reproduces its published analysis of variance
(treatment F = 5.36 against the published 5.35), and a test checks it.simulate_solomon() generates a randomized Solomon study with chosen
treatment, pretest, and sensitization effects, and attaches the true
value of every estimand. It uses the data-generating model of
power_solomon() (validated in #18), with a pretesting main effect and
a location added. With solomon_example's settings and seed it
reproduces solomon_example exactly, and a test checks this.fit_solomon_1949() reproduces the analysis Solomon (1949) proposed
with the design. The unpretested groups get an inferred pretest mean, each
group gets an improvement score, and the interaction is
I = d1 - (d2 + d3) in the three-group design, or I = d1 - (d2 + d3 - d4)
in the four-group design (pp. 141-147). It works from individual data or
group means. Like Solomon, it reports point estimates without a test. It
is labeled historical, with Campbell and Stanley's (1963/1966, p. 25)
verdict on gain-score analyses.solomon1949 holds the group means of Solomon's spelling experiment
(Tables II and III, pp. 144-145). The function reproduces his published
interactions, -2.2 and -3.1.mai2020 holds the individual data of Mai et al. (2020), a
randomized Solomon design with pretesting crossed with relapse
prevention, goal setting, and a control condition. The authors published
the data with the article under CC BY 4.0. The help page gives the
license, the changes made, and the points where the article and the data
disagree. inst/COPYRIGHTS and the Copyright field of DESCRIPTION
record the copyright holders.fit_solomon_classic()
and fits the recommended model with fit_solomon_glm().report_solomon() drafts it.baseline_solomon() compares the two pretested arms at pretest, from
individual scores or from published summary statistics, with the mean
difference, a pooled t test, and Hedges's g with its noncentral-t
confidence interval. The unpretested arms have no pretest, so their
baseline cannot be checked; the printout says so.report_solomon() gains design$assignment ("random" or
"nonrandom"). For nonrandomized designs, results speak of differences
between groups rather than treatment effects, and the design statement
names the threats that random assignment would otherwise control, following
Edmonds and Kennedy (2017, pp. 7–8, 94). It adds that the unpretested
arms have no baseline and, without random assignment, form a static-group
comparison whose groups cannot be shown equivalent (Campbell & Stanley,
1963/1966, pp. 12, 25). Baseline comparisons are reported too.elkarkri2025a gains the pretest means and standard deviations of the two
pretested classes (El Karkri et al., 2025a, Table 7, p. 10), which differed
at pretest.marginal_solomon() now accepts logistic fits with robust = "CR2";
clustered count fits, which the study did not cover, are refused with a
pointer to alternatives. Delta-method standard errors use the CR2
covariance (Bell & McCaffrey, 2002), and intervals and tests use the t
distribution with Satterthwaite degrees of freedom for the linearized
contrast (Pustejovsky & Tipton, 2018). Effects gain a df column, and
degrees of freedom below 4 give the classed small-df warning (Tipton,
2015). The bootstrap is refused for clustered fits, because it resamples
participants rather than clusters.marginal_solomon(method = "cluster_summary") for clustered binary
fits. It compares the unweighted means of cluster-level proportions with
t intervals that use separate variances and Satterthwaite degrees of
freedom (Hayes & Moulton, 2017, pp. 211–215), as the pre-registered
study's comparator did. It works whether whole clusters were assigned to
the four cells or pretesting was assigned within clusters. It warns
below four clusters per arm (p. 128).invariance_solomon() tests measurement invariance of a set of
indicators across the four Solomon groups: configural, metric, and scalar
models in the sequence Vandenberg and Lance (2000) recommend. At each step
it reports the chi-square difference test, scaled for robust estimators
(Satorra & Bentler, 2001), and the change in CFI, RMSEA, and SRMR against
the cutoffs of Chen (2007). It gives the decision under each criterion.
The two criteria can disagree, so the function decides nothing for the
user. A criterion whose statistic cannot be computed is reported as
undetermined.fit_solomon_sem_latent() now runs invariance_solomon() on the POST
indicators first. It warns (class solomonR_invariance_warning) when a
criterion does not support scalar or partial scalar invariance, and it
stores the result in invariance. It never refuses the contrasts.
check_invariance = FALSE skips the check.fit_solomon_sem_latent() gains partial_post and partial_pre for
partial-invariance models (Byrne et al., 1989). The freed parameters must
involve only a minority of the indicators (Vandenberg & Lance, 2000,
p. 38), and at least two indicators must stay fully invariant.fit_solomon_classic() and plot_classic_flow() gain flow = "1995",
the revision that removed Test D (Walton Braver & Braver, 1995, as cited in
Sawilowsky, 1996, p. 2). The remaining tests follow the 1988 rule, as in
Sawilowsky's (1996) simulation of the revised sequence. The default, 1988,
is unchanged.alpha_allocation option for the 1995 flow: Sawilowsky's (1996,
Table 4) Methods 1 and 2, under Bradley's conservative and liberal
robustness criteria as he applied them, with the published test-wise
levels. print(), plot_classic_flow(), and report_solomon() show the
levels used.fit_solomon_classic() reports these results.fit_solomon_classic() when
Test I is reached, and the Test I rates of power_solomon().p_one_tailed.
stouffer_solomon() gains p_meta_two_tailed.elkarkri2025a and kvalem1996 hold the published Solomon
results of El Karkri et al. (2025a; posttest statistics of four intact
classes) and Kvalem et al. (1996; condom use in a class-randomized trial),
with their sources, designs, and caveats on the help pages. Tests
reproduce the published ANOVA and chi-square results from them.report_solomon() turns a fitted Solomon analysis into APA 7 results
sentences, a design statement, and the APA 7 references for exactly the
methods and options the analysis used (for example, CR2 standard errors,
the 1990 decision flow, or cluster-level permutation). It supports the
fits of fit_solomon_glm(), fit_solomon_ml(), fit_solomon_classic(),
perm_solomon(), marginal_solomon(), equivalence_solomon(),
fisher_solomon(), solomon_from_summary(), fit_solomon_sem(), and
fit_solomon_sem_latent(), in plain text or Markdown.tools/check-references.R now also checks, and a test fails if an
exported analysis function has no registered references.fit_solomon_sem() and fit_solomon_sem_latent() no longer request
global fit indices for saturated models (df = 0), where they are not
diagnostic. This removes the lavaan warnings about robust CFI and RMSEA
that the four-group mean-structure model produced; such fits report
df = 0 and missing indices, and print that global fit is not
diagnostic.plan_solomon(), power_solomon(), and plot_power_solomon(), with
planning values from the meta-analysis of Willson and Putnam (1982) and
the caution of McCambridge et al. (2011). It shows why sensitization needs
about four times the sample of the average treatment effect, how the
pretest-posttest correlation and the allocation change the plan, and when
to plan by simulation.solomon_from_summary() reanalyzes a published Solomon study from the
posttest n, mean, and SD of the four groups: the two-way ANOVA with Type
III sums of squares, Tests A-D, the pretest main effect, and the simple
effects, with confidence intervals. It reproduces the F tests of El Karkri
et al. (2025a) from their Table 8 within rounding.solomon_effect_sizes() returns effect sizes for meta-analysis in
yi/vi form: Morris's (2008) d_ppc2 for the pretested pair, with its
Eq. 25 variance, and Hedges's g for the unpretested pair. The Eq. 25
variance reproduces all 54 theoretical values in Morris's Tables 2 and 3,
and the help page states its underestimation when treatment inflates
posttest variance.fit_solomon_classic() and plot_classic_flow() gain flow. "1988",
the default, keeps the original sequence of Walton Braver and Braver
(1988) and leaves existing results unchanged; "1990" follows the
authors' amendment (Braver & Walton Braver, 1990), in which every test
through Test I is run once Tests A and D are nonsignificant and Test I is
regarded as the most definitive.fit_solomon_classic() returns a history/maturation check (history):
the unpretested control posttest (O6) compared with the pretests of the
pretested groups (O1, O3) by independent-samples t tests, as Mai et al.
(2020) report. It is printed as a historical check.fit_solomon_glm(family = "negative_binomial") fits the NB2 model by
maximum likelihood with MASS::glm.nb() (Venables & Ripley, 2002), with
the same Solomon model and exposure offsets as the Poisson fit and HC3
standard errors by default (Cameron & Trivedi, 2013). It returns and
prints the estimated theta, and gives a classed warning
(solomonR_theta_boundary_warning) when theta does not converge because
the counts show little overdispersion. marginal_solomon() accepts these
fits. MASS is a new import.perm_solomon() now accepts clustered fits and permutes whole clusters.
It supports clusters assigned to the four Solomon conditions (permuted
within pretest conditions) and treatment by cluster with pretesting
within clusters (permuted across clusters); designs that assign treatment
within clusters are refused. The statistic uses covariate-adjusted
cluster-level summaries (Gail et al., 1996; Hayes & Moulton, 2017), and
every allocation is enumerated, with an exact p-value, when there are at
most reps.statistic argument: "studentized" (default) or "difference".
Results report the estimate, the level permuted, whether the p-value is
exact, and the numbers of treated and control clusters.solomonR_unbalanced_clusters_warning) is given when
treated and control clusters differ in number.marginal_solomon() pointed clustered designs to perm_solomon(); #64,
below, added marginal contrasts for clustered binary fits.fit_solomon_glm() gains exposure, a log offset for counts observed over
different times or exposures (log-link families only), and returns the
Pearson dispersion statistic for binomial and Poisson fits.marginal_solomon() accepts Poisson fits: the Solomon contrasts as rate
differences and rate ratios per unit of exposure, standardized over each
pretest condition, with delta-method intervals from the robust covariance
(Cameron & Trivedi, 2013).marginal_solomon() estimates the Solomon contrasts for binary
outcomes as risk differences, risk ratios, or odds ratios from marginal
(standardized) risks, following Daniel et al. (2021) and Localio et al.
(2007). Intervals come from a bootstrap that resamples within the four
Solomon cells, or from the delta method.fisher_solomon() reproduces the historical categorical analysis of
El Karkri et al. (2025b), with a caution that its rule compares
significance, not effects.fit_solomon_glm() now warns (solomonR_noncollapsible_warning) when a
noncollapsible link such as the logit is combined with y_pre:
its Pretest x Treatment contrast then compares a conditional with a
marginal effect and is nonzero without sensitization.validate_solomon() gains a cluster argument. It reports the number of
clusters and cluster sizes in each cell, and whether treatment and
pretesting were assigned to whole clusters or within them. A cell made up
of a single cluster is an error, because cluster and condition are then
completely confounded, as when each Solomon condition is one intact class.fit_solomon_glm(robust = "CR2") refuses such designs with a classed
error (solomonR_confounded_clusters) instead of reporting cluster-robust
standard errors that cannot be estimated.solomonR_small_df_warning) when a
Solomon contrast has Satterthwaite degrees of freedom below 4, where Tipton
(2015) advises that p-values not be trusted.plot_sensitization() now accepts fit_solomon_ml() fits. Intervals for
the adjusted cell means use the fit's own inference: the normal reference
under the default Wald inference, or Welch-Satterthwaite t under
inference = "satterthwaite". fit_solomon_ml() now stores what those
intervals need; its estimates, standard errors, and intervals are
unchanged.test
column of power_solomon() and the committed validation tables; no
numeric result changes.plan_solomon() (#24). Fifty-six analytically
planned designs were re-simulated with the package's GLM test, with no
failed fits. From 30 participants per cell, 37 of 39 plans reached the 80%
target within 0.02, and the two exceptions were above it. A new article,
"Checking plan_solomon()", reports every plan.studies.csv has one row per study
and benchmarks.csv has one row per scenario, method, estimand, and
performance measure, with Monte Carlo standard errors. Failed fits are
counted separately, and measures a method cannot have are listed with a
reason rather than omitted.plot_power_solomon() draws power against the size of the smallest
cell for each Solomon estimand, with the target power marked and the
design plan_solomon() returns for that target. Curves use the validated
normal-theory power by default; method = "simulation" uses the package's
GLM test through power_solomon() and shows two-MCSE bands. One of
delta, sens, or rho may vary across curves.plot_solomon_design() draws the four-group design in Campbell and
Stanley's (1963) notation. Without data it gives the teaching schematic;
with data or a GLM fit it labels each group with its size and posttest
mean and flags empty or sparse groups, using the rule in
validate_solomon().plot_solomon_change() shows pretest-to-posttest change for the
pretested groups, with t intervals, beside posttest means for the
unpretested groups, which are labeled as unpretested by design.
Pretested participants with incidentally missing pretests are excluded
from the trajectories and counted in the caption, never imputed.plot_classic_flow() draws the historical Tests A-I sequence as a
decision tree. Given a fit_solomon_classic() result, it highlights the
path taken with each test's p-value. Every version carries the caution
that the conditional sequence inflates Type I error (Sawilowsky et al.,
1994).plot_sensitization() draws the Pretest x Treatment interaction as
model-adjusted group means with confidence intervals. Pretested groups are
evaluated at the mean pretest among pretested participants and unpretested
groups without a pretest, so the difference of differences among the
plotted means equals the fitted sensitization contrast exactly. Observed
means are overlaid for comparison.equivalence_solomon().plot_solomon() and plot_solomon_gg() now use t intervals with n - 1
degrees of freedom for cell means instead of the normal quantile, which was
too narrow with small cells.plot_solomon_effects() draws the four Solomon contrasts with their
confidence intervals from a fit by fit_solomon_glm(), fit_solomon_ml(),
fit_solomon_sem(), or fit_solomon_sem_latent(). Estimates and intervals
are taken unchanged from the fitted object, and the caption states the
confidence level, the inference used, and the reference distribution.equivalence_solomon().plan_solomon() finds the smallest Solomon design, at a chosen
allocation across the four cells, whose power for each estimand reaches a
target. Analytic planning uses the normal-theory benchmarks validated in
#18 and returns the exact minimum. method = "simulation" plans for the
package's own GLM test through power_solomon(), which matters with small
cells, where HC3 standard errors are conservative.power_solomon() is rebuilt. It reports the rejection rate of each Solomon
test with its Monte Carlo standard error, names the estimand, the test, and
the true effect behind every row, and gains alpha and seed arguments.
The global random number state is restored after use.sigma
applies to every cell.NA rather than zero power when stouffer = FALSE.fit_solomon_glm(robust = "CR2") now uses Satterthwaite degrees of freedom
for coefficient and contrast tests (Pustejovsky & Tipton, 2018), matching
clubSandwich. The previous normal-reference CR2 tests over-rejected with few
clusters (#14). Coefficient and contrast tables gain a df column (Inf for
normal-reference tests).fit_solomon_glm(robust = "CR2") no longer fails when outcomes are missing;
the clustering variable is aligned with the rows used by the model (#14).perm_solomon() refuses fits that include a clustering variable, because
permuting individuals is not a valid randomization test when treatment was
assigned to clusters (#15). Cluster-level randomization inference is planned
(#19).fit_solomon_sem_latent() fixes a reference latent mean (U0; P0 in the
latent ANCOVA) so the latent mean structure is identified. Solomon contrasts
are unchanged; model degrees of freedom and fit indices are now correct
(#16).fit_solomon_glm() now defaults to robust = "HC3", following Long & Ervin
(2000) and Hayes & Cai (2007).fit_solomon_glm(), fit_solomon_classic() (Tests
A-H), fit_solomon_ml(), fit_solomon_sem(), and fit_solomon_sem_latent()
gain conf.low and conf.high columns and a conf_level argument. ML and
SEM intervals are large-sample Wald intervals.solomon_example data set: a simulated Solomon four-group study with 30
participants per group, generated by a documented script with a seed and
parameters fixed in advance, so users can compare estimates with known true
effects. It is now the example in the README, help pages, and vignettes.solomon_demo is kept as a second example. Its documentation now describes
the negative pretest-posttest correlation and chance pretest imbalance that
make unadjusted, ANCOVA, and gain-score estimates disagree.vignette("getting-started") follows solomon_example from design
checks through the historical workflow, the recommended analysis, an
equivalence test for sensitization, and a method comparison to a reporting
example, with an annotated reading list.fit_solomon_ml() gains inference = c("wald", "satterthwaite"). The
default keeps van Engelenburg's (1999) Wald inference. The small-sample
option keeps the maximum-likelihood point estimates but uses unbiased
residual variances within each pretest condition, t tests within a
condition, and Welch-Satterthwaite degrees of freedom for contrasts that
combine conditions (Satterthwaite, 1946; Welch, 1947). Coefficient and
effect tables gain a df column.inference is
not supplied, fit_solomon_ml() warns with class
solomonR_small_sample_warning, and printed output notes the small cells.
Supplying inference = "wald" keeps the default without the warning.compare_solomon_methods() reports both inference options for maximum
likelihood.fit_solomon_ml(). Its default Wald intervals were too narrow
in small samples (mean coverage 0.893 with 6 participants per cell and
0.936 with 20; sensitization Type I error 0.099 with 6 per cell). The
small-sample option was calibrated at every cell size studied (mean
coverage 0.949 to 0.950; Type I error 0.050 to 0.053). The unified GLM with
HC3 was conservative at 10 or fewer per cell and close to nominal from 20.vignette("solomon-methods") labels each analysis as a
historical procedure, contemporary recommendation, published Solomon
proposal, or solomonR extension, and states its estimand, assumptions,
limitations, and sources. Historical claims were checked against the
sources, including Campbell and Stanley (1963), Braver and Braver (1988),
and Sawilowsky et al. (1994).compare_solomon_methods() fits the unified GLM, maximum likelihood,
classic Tests A-F and H, and SEM to the same data and aligns their estimates
of the four Solomon contrasts with each method's pretest adjustment,
variance assumption, reference distribution, and interval. Analyses that do
not estimate a raw-scale contrast (permutation tests, Test I, latent SEM,
Hedges' g) are listed separately with the reason (Lin, 2013; Lundberg et al.,
2021).equivalence_solomon() performs a two one-sided tests (TOST)
equivalence test for a Solomon contrast, by default the Pretest x Treatment
sensitization contrast (Schuirmann, 1987; Lakens, 2017). It uses the fitted
model's reference distribution, reports both one-sided tests, the
1 - 2 alpha interval, and the test against zero, and classifies the result
as equivalent, trivially small, different, or inconclusive. Bounds have no
default and are documented as a prespecified smallest effect size of
interest.validate_solomon() checks input lengths, 0/1 coding, the presence of
all four cells, and observed outcomes per cell, and returns every problem
as an error, warning, or note instead of stopping at the first.check_solomon_missing() separates structurally absent pretests in the
unpretested groups from incidental pretest and posttest missingness,
unexpected pretest scores, and unassigned participants. It reports counts by
cell and cited guidance for each category (Solomon, 1949; Rubin, 1976;
Graham et al., 2006; White & Thompson, 2005; Groenwold et al., 2012; Little &
Rubin, 2019).fit_solomon_glm(), fit_solomon_sem(), fit_solomon_sem_latent(), and
check_solomon_assumptions() require treat and pretested to be coded 0/1
(or logical) and inputs to have equal lengths, instead of returning empty or
rescaled results (#5).fit_solomon_glm() warns when pretested participants are missing pretest
scores (they are excluded, not imputed) and when pretest scores are supplied
for unpretested participants (#5, #6).power_solomon() now warns that it is experimental. Interim fixes: sigma
applies to every cell, the Stouffer arm uses the historical one-tailed
direction, disabled metrics are NA, and delta is documented as the effect
among unpretested participants. A validated rebuild is planned (#18).perm_solomon(seed = ) restores the global random-number state on exit.print() returns the fitted object invisibly.plot_perm() reports the same corrected p-value as perm_solomon().check_solomon_assumptions() presents its results as descriptive
diagnostics rather than gates for choosing an analysis, and uses complete
pretested cases for the slope-homogeneity test.procedure column.inst/CITATION uses bibentry().spr2_ci(), which relied on an invalid interval
transformation, and duplicated print helpers.Set the v0.3.0 scope around graduate students and applied researchers and added v0.4.0, v0.5.0, v0.6.0, and v1.0.0 milestones that mirror the roadmap.
solomonR 0.3.0 and later is licensed under GNU GPL version 3 only (GPL-3). Version 0.2.0 and earlier retain their original MIT terms and notices.
Aligned development citation metadata, license pages, and roadmap/issue links.
Distinguished completed implementation, deferred work, and research proposals in the roadmap without changing analytical behavior.
Formatted LICENSE.md as markdown so the pkgdown license page has a title
and readable headings; the license wording is unchanged.
Added Language: en-US and a spelling word list (inst/WORDLIST) so
documentation spell checks report only genuine errors.
Began development toward solomonR 0.3.0.
Added R-universe distribution and stable-release installation instructions.
Reconciled the development roadmap with functionality delivered in v0.2.0.
fit_solomon_classic().[PATH] markers.fit_solomon_glm() as the primary unified Solomon analysis.treat + 0.5 * treat:pretested.perm_solomon() as a stratified treatment-label permutation test.plot_perm().fit_solomon_ml() for full-information maximum-likelihood analysis.fit_solomon_sem().fit_solomon_sem_latent().