Design, Measurement, and Analysis in R (DMAR)
Overview
Methods for design, measurement, and analysis, with the aim of being user friendly yet methodologically sound. 'DMAR' (pronounced "Dee-Mar") implements many advanced and nonstandard methods and makes them available for straightforward use, with interfaces, defaults, and documentation that are consistent across the package and grounded in the methodological literature, in support of sound and reproducible results. The package emphasizes effect size estimation with confidence intervals; sample size planning through accuracy in parameter estimation (AIPE) and power analysis (including composite power for designs whose conclusions require several results to hold at once), with minimum risk, sequential, and equivalence frameworks; reliability, agreement, and measurement more broadly, from coefficient omega with confidence intervals to measurement invariance; factor analysis and structural equation modeling, in which constructs, latent variables measured by multiple indicators, are modeled directly, with confirmatory factor analysis, convergent and discriminant validity, and sample size planning for structural equation models; mediation analysis, from the simple mediation model with bootstrap intervals to likelihood ratio tests of arbitrary indirect effects by model-based constrained optimization (MBCO), with multiple groups and the probing of moderated mediation; equivalence and noninferiority testing; meta-analysis; repeated measures, multivariate, ANOVA, and ANCOVA designs; and inference grounded in model comparison throughout. Measurement is approached from a psychometric perspective, and although many of the methods grew up in human-centered research, they apply broadly across the empirical sciences. Much of what is implemented traces to the author's methodological work, interests, and collaborations. 'DMAR' is a more modern, more general, and greatly expanded reimagining of the 'MBESS' package (Kelley, 2007a, doi:10.18637/jss.v020.i08; 2007b, doi:10.3758/BF03192993), which has been on CRAN for more than two decades and remains available there in stable form. Most functions accept either raw data or the summary statistics typically reported in published articles, so an analysis can be reproduced from a paper without the original data, which is useful both for extending a published analysis and for meta-analytic work. The estimation, inference, and planning functions return one consistently formatted data frame per function that composes with the broader R ecosystem, and confidence intervals are reported alongside effect sizes throughout, as best practice recommends. Researchers who have data and a question but who are not R experts will find the package approachable, while methodologists gain access to advanced and nonstandard methods, including tables of critical values not available elsewhere.
First public release of DMAR (pronounced "Dee-Mar," for "Design,
Measurement, and Analysis in R"), a greatly expanded reimagining
of the MBESS package.
Every Example Runs, and Nothing Writes or Seeds Behind the User's Back
- Every line of code in every help page example now runs. Earlier drafts carried a slow call (a bootstrap interval, a Monte Carlo planner, a refit) as a comment so that a reader could see the syntax without the check paying for it; the CRAN review of 2026-09-04 asked that no example line be commented out, and none is. Where a call was slow, it runs with a small replication count and a comment naming the count a reported analysis deserves (the defaults are unchanged); where a page demonstrated the same thing twice, it now demonstrates it once. The package still ships no
\donttest{}and no\dontrun{}, and a parse-based detector in the test suite fails on any comment line that would parse as code.
Show all changes in 1.0.0Hide the rest of the changes in 1.0.0
- The sensitivity family no longer writes a file unless asked to, and never to a default location. The
saveargument is gone from <<SAVE_LIST>>; the single switch isfilename, which defaults toNULL. Supplying a path writes the per-replication results there exactly assave = TRUEused to; a throwaway run points it attempfile(fileext = ".csv"). - A supplied
seedis now set throughwithr::local_seed()(withr, which has no dependencies of its own, joins Imports), by way of one internal helper that every seeded function calls. The behavior is what it was, the user's generator state is restored when the function returns, but the package no longer touches.Random.seedor the global environment to do it, and no function uses<<-: the handlers that count clamped or non-converged replications keep their counts in a local environment. - The six Monte Carlo functions that silenced every warning for their duration with
options(warn = -1)now muffle only the warnings their loops are known to raise (lavaan convergence and variance warnings on borderline replicates, the noncentral clamp); any other warning reaches the user. - The Bryant-Paulson distribution function integrates over the covariate shrinkage factor after the change of variables delta = 1 - u^2, under which the Beta weight of Bryant and Paulson (1976, Equation 12) is smooth on the unit interval for every number of covariates instead of carrying an integrable singularity at the endpoint where the distribution puts most of its mass. The two forms agree to about 1e-10 (checked on a grid of 288 quantile, covariate, group, and degrees of freedom combinations), the Table 1 reproduction in the tests is unchanged, and a critical value now costs about a twentieth of what it did, which is what lets every
qbryant_paulson(),cv_bryant_paulson(), andci_c_ancova_bp()example run live. - Two smaller changes from the same pass.
mlmr(),mlmr_mv(), andaverage_variance_extracted()resample throughlavaan::lavBootstrap(), the entry point that replacedbootstrapLavaan()in lavaan 0.7-2 (the package already requires that version); the results are identical. The five sensitivity functions whose...was never forwarded anywhere (ss_aipe_sc_sensitivity(),ss_aipe_smd_sensitivity(),ss_aipe_sm_sensitivity(),ss_aipe_R2_sensitivity(), andss_power_R2_sensitivity()) no longer accept it, so a misspelled or retired argument such assave = TRUEnow stops with an error instead of being swallowed.ss_aipe_cv()withassurancesupplied reports its noncentral accuracy note once, with the combined count, where it used to report it twice; andss_aipe_cv_sensitivity()andss_aipe_sc_ancova_sensitivity()report that note once per run, with the number of replications it arose in, rather than once per replication.
An Adversarial Quality Control Pass
- A package-wide audit (numerical verification against complex-step derivatives and Monte Carlo, documentation contracts run rather than read, and mechanical convention gates) closed out with these fixes.
analysis_of_change()now fits an intercept-only polynomial (order = 0) under both methods; it previously stopped insidestats::poly(), and its no-fit message for the polynomial now counts occasions instead of suggestingstart, which the polynomial rejects. - The equivalence sensitivity siblings speak their parents' language:
ss_aipe_equivalence_smd_sensitivity()takesdelta_lower/delta_upperandss_aipe_equivalence_r_sensitivity()takesrho_lower/rho_upper, positive magnitudes with the upper bound required and the lower defaulting to symmetric, exactly as inequivalence_smd()andequivalence_r(). The signedequivalence_lower/equivalence_upperspellings, and their silent default of plus or minus 0.20, are gone. - Every AIPE planner that reports an expected interval width names the row
ci_width_expectedand reports the expected full width:ss_aipe_equivalence_smd()andss_aipe_mixed_effects()previously reported the half-width asci_half_width_expectedwhiless_aipe_equivalence_r()reported the full width, a trap for anyone extracting the row programmatically. - The equivalence trio attaches the
conf_levelattribute theci_*family always carried, and theequivalence_c()verdict label is spelled"Noninferior only", matching the solidnoninferiorthe rest of its page uses.equivalence_r()now validates raw data (matching lengths, at least 4 complete pairs) the way its summary-statistics path always did.convert_r_Z()andconvert_Z_r()insist on a single value, as documented; vector input previously recycled the term column into duplicated rows. A follow-up ruling extended the same single-value guard to the whole scalar conversion family (convert_R2_f()and its three siblings,convert_delta_lambda()and its inverse, andconvert_z_normal()), with domain checks where a map's algebra ends (anR2at or past 1, a nonpositive group size), so no conversion can recycle vector input into duplicated rows. - Documentation corrections from the same audit: the four nonlinear simulators state that the first-order delta method behind
reliabilityandreliability_by_occasioncan drift from the realized variance ratio when random variances are large, and document thescheduleattribute; the Richards example comment places the delta = 3 inflection at about 63% of total change, per its own formula; the mixed-effects examples on?analysis_of_changenow run live.
One Prefix for Every Confidence Interval
- The four multiple-comparison interval functions moved into the
ci_*family:ci_dunnett,ci_scheffe,ci_games_howell, andci_tukey_kramerreplacedunnett_ci,scheffe_ci,games_howell_ci, andtukey_kramer_ci. The suffix forms were the only four exports naming a confidence interval outside the family prefix, and each function now pairs with its critical-value sibling (cv_dunnett,cv_scheffe,cv_tukey_hsd). The package is unreleased, so the old names are gone rather than aliased. - The noncentral-distribution toolkit is named by one rule (2026-08-21):
nc_and then the distribution, soci_nc_t(),ci_nc_F(), andci_nc_chisq()replaceconf_limits_nct(),conf_limits_ncf(), andconf_limits_nc_chisq()(the snake-cased descendants of MBESS'sconf.limits.nct()and kin), andmoments_nc_t()andmoments_nc_F()replacemoments_nct()andmoments_ncf()to matchmoments_nc_chisq(). The intervals join theci_*family because a confidence interval, on the noncentrality parameter that the effect size intervals are built from, is what they compute, and "confidence limits" was vocabulary that existed only in MBESS. Splittingncfrom the distribution token retires the one inherited exception (nct,ncfagainstnc_chisq) and restores the capital \emph{F} the package writes everywhere else (F_value,convert_F_chisq). The noncentral marker stays because the noncentrality parameter is the estimand.plot_ci()keeps its name: it is a plot first. The old names are gone rather than aliased; each page names its earlier self in the description. - The correlation intervals now carry the names of their estimands, matching the rest of the correlation family (
ss_aipe_r,ss_power_r,var_r,expected_r,equivalence_r):ci_r()is the confidence interval for the simple Pearson correlation (renamed from the MBESS-heritageci_cc(), with the estimate row renamed fromest_cortor), andci_R()is the interval for the population multiple correlation coefficient (its former lowercase alias spelling is gone). Cross-references across the package were audited against this distinction and every one now points at the interval it meant. Because the two natural file names differ only by case, which case-insensitive filesystems refuse, both functions live inR/ci_correlation.Rand share theci_correlationhelp page. - Kish's design effect function is
design_effect(); the abbreviationdeft()is gone as a function name, while the returned table keeps itsdesign_effectanddeftrows, deft being the standard term for the standard error inflation factor, the square root of the design effect. - The remaining exported alias pairs were resolved to single names. Fisher's Z is written with a capital Z throughout the package, because it is the variance-stabilizing transform of a correlation and not a z-score, so the converts are
convert_r_Z()andconvert_Z_r()only (the lowercase spellings are gone) and the prose and math were swept to match. The limits of agreement function islimits_of_agreement(), withloa()kept as its short alias andbland_altman_loa()gone (the method is named for what it computes; Bland and Altman are credited in the references).reliability_omega_categorical()andcovmat_from_cfa()are the only names for those functions; thereliability_omega_c()andcovmat_from_cfm()aliases are gone. The dataset alias bindingsHS_DataandPrime_Timeare gone as well: every dataset carries exactly one name, the documented snake_case one, and unlike the alias bindings the canonical names work withdata().
Fitting Change Models, Linear and Nonlinear
- The vocabulary of the longitudinal simulators names what the rows are: the identifier column identifies units (persons, animals, trees, classrooms),
ncounts units, and the formergroupcolumn ispopulation, one level per data generating parameter vector. - Measurement schedules can now be unit-specific, in every simulator: in place of a shared
target_timesgrid,time_range = c(lower, upper)draws each unit's own measurement times uniformly between the bounds, withoccasionsfixing the number of times per unit orc(min, max)letting it vary, so designs such as age at testing rather than grade at testing are simulated directly. The polynomial simulator additionally requires every unit's count of occasions to reachP + 1, so each simulated trajectory identifies the polynomial it came from. analysis_of_change()closes the loop the simulators open: it fits any of the four nonlinear change models, or a polynomial of any order, to longitudinal data. The default two-stage method fits one curve per unit, from that unit's data alone, with data-driven starting values, and summarizes the unit-level parameters by their mean, their standard deviation and variance across units (the individual differences), and the standard error of the mean;method = "mixed"instead estimates the proper random-coefficients model simultaneously,lme4::lmer()for the polynomial andnlme::nlme()for the nonlinear curves started at the two-stage estimates, sosd_unitsbecomes a variance component purged of estimation noise. The help page positions the function candidly againstnlme::lmList(),nlme::nlsList(), and the self-startingSS*curves: what it adds is the landmark parameterizations, the simulator match, and one tidy interface across linear and nonlinear change. With a single trajectory (orid = NULL) it reduces to one nonlinear least squares fit reported with asymptotic standard errors, so N = 1 is one unit's change. Non-converging units are dropped with a single counted warning and the effective count travels as then_usedattribute; the full matrix of unit-level estimates rides along for plotting or as starting values for a simultaneousnlme::nlme()fit, and the help page states plainly that the between-unit spread of estimates includes estimation noise, which a variance-component model separates.
Nonlinear Growth Curve Simulators
- Four random-coefficients nonlinear change simulators join
simulate_longitudinal_polynomial(), sharing its interface (several populations of units, between-unit parameter variances and correlations, level-one error by variance or by target reliability, error correlation structures, assessment-time jitter) and its long-format return that feedsplot_trajectories()and nonlinear mixed-model fitters:simulate_longitudinal_negative_exponential()(asymptotic regression),simulate_longitudinal_logistic(),simulate_longitudinal_gompertz(), andsimulate_longitudinal_richards(), whose shape parameter delta subsumes the logistic (delta = 1) and the Gompertz (delta -> 0) as special cases, relations the tests pin exactly. The parameterizations are those of Kelley (2005, dissertation; 2008, Methodology), in which every parameter is a landmark of the change process (floor, ceiling, moment of fastest change, curvature, inflection height) and the intercept-shifting zeta frees the lower asymptote from zero; the Richards application follows Guo, Cheng, and Kelley (2016). A new vignette, "Nonlinear Growth Curves and the Meaning of Their Parameters", illustrates all four curves, the Richards unification, and the polynomial comparison: a ninth-order polynomial needs ten uninterpretable coefficients to track a four parameter Gompertz inside the data and still collapses the moment it extrapolates.
One Word for the Equivalence Family
- The equivalence tests are named for the question they answer:
equivalence_smd(),equivalence_r(), andequivalence_c()replacetost_smd(),tost_r(), andtost_c(), and the AIPE planners follow (ss_aipe_equivalence_smd(),ss_aipe_equivalence_r(), with their sensitivity siblings). The whole family now speaks the same word as the planning and plotting surfaces that always did (power_equivalence_md(),ss_power_equivalence_c(),plot_equivalence()). The procedure is unchanged, Schuirmann's two one-sided tests, and each help page says so by that name; the reported TOST \emph{p}-value keeps its standardp_tostterm. The old names are gone rather than aliased.
Sample Size Planning for Correlation Equivalence
ss_aipe_equivalence_r()plans the sample size for an equivalence question about a Pearson correlation: the smallest \emph{N} whose 100(1 - 2 alpha)% Fisher's \emph{Z} interval (the intervalequivalence_r()andci_r()invert) has expected width at or below the target, with an optional Monte Carlo assurance correction. At the conservative default planning value of 0 the answer has a closed form, and the tests anchor the search to it. Its Monte Carlo siblingss_aipe_equivalence_r_sensitivity()follows the family API and reports, alongside the family's width and coverage summaries, the realized proportion of equivalence verdicts inside the chosen bounds. This fills the gap noted when the equivalence family was reviewed: the SMD had an AIPE planner for its equivalence interval and the correlation did not.
The Examples Teach From the Package's Own Data
- The help-page examples now use DMAR's own datasets rather than the base-R teaching sets: Dunnett-style comparisons run on
depression_bdiwith its wait list control, the studentized range procedures ontest_market's six panels, the unequal-variance and ran
The NEWS section is longer than shown here.
From NEWS.md in the release
Install
Health
- OK13 OKNow
- OK5 OK2026-09-22
Documentation
- Help pages
- 322 (3 internal)includes a package overview page
- Examples that run
- 100%312 run in a plain check
- Exported functions with examples
- 100%
- Documented parameters
- 91%
- Return-value docs
- 100%
- Help pages citing references
- 87%
- Introduction to DMAR
- Composite Power for Factorial ANCOVA: Planning Simple Effects, an Interaction, and a Moderator
- Composite Sample Size Planning for SEM: A Simple Model and a Latent Growth Curve
- Heterogeneity of Regression in the Pygmalion Data
- How DMAR's Functions Fit Together: A Deep Dive
- Maximum Likelihood Multiple Regression and Multivariate Regression
- Moving From MBESS to DMAR: A Migration Guide and a Tour of the New Methods
- Nonlinear Growth Curves and the Meaning of Their Parameters HTML
- Power and Precision for the One-Way ANOVA: A Model Comparison Perspective
- Power for Factorial ANCOVA: A 2 x 4 x 3 Design Worked in Full HTML
Show 8 moreHide 8 vignettes
- Reading DMAR Result Tables
- Reliability in DMAR: Choosing the Coefficient, Choosing the Interval
- Reproducing the Textbook Critical-Value Tables
- Simultaneous Comparison of Adjusted Means in ANCOVA With DMAR
- Sums of Squares in Nonorthogonal Designs
- The Teacher Expectancy Meta-Analysis: Reproducing Raudenbush (1984) HTML
- Visualizing Effect Sizes and Distributions With DMAR HTML
- Weighted Kappa: Cohen's 1968 Illustration, Worked in Full
Downloads
Repository
Forks over time
Releases over time
Commits over time
11 development-tooling and community-health practices detected across 6 families in the upstream repository
Checks run against github.com/yelleknek/dmar on 2026-10-18.
The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel
GitHub Pages site last deployed 2026-10-15 · The repository has a site deploy workflow
pkgdown site last built 2026-10-15
Show all practicesHide 2 practices
Dependencies
Code & Tests
Datasets
People & History
- 1.0.0Latest2026-09-21 · current release
- RR 4.6.0 released · 2026-04-24
Package metadata
- First published
- 2026-09-21
- Total releases
- 1 / 1 yrs
- License
- GPL (>= 3) OSI
- Minimum R
- ≥ 4.0.0
- Bundled data
- 383 KB / 9 files
- Download size
- 6.5 MB
Cite
Cite this package
Run in R for the authors' preferred citation:
citation("DMAR")The package provides a citation file that builds its entry when R runs it. Run citation() to see it.
The repository also keeps a CITATION.cff.
Cite the R Observatory
For a number measured here: a download total, a coverage figure, an archival date.
From data release v2026-10-20, which the citation names so these numbers can be found later. More on citing and the projects behind them.