Skip to content

Design, Measurement, and Analysis in R (DMAR)

0packages depend
627downloads / year
82.7%test coverage
13/13flavors OK

Overview

About

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.

Changes in 1.0.0

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 save argument is gone from <<SAVE_LIST>>; the single switch is filename, which defaults to NULL. Supplying a path writes the per-replication results there exactly as save = TRUE used to; a throwaway run points it at tempfile(fileext = ".csv").
  • A supplied seed is now set through withr::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.seed or 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(), and ci_c_ancova_bp() example run live.
  • Two smaller changes from the same pass. mlmr(), mlmr_mv(), and average_variance_extracted() resample through lavaan::lavBootstrap(), the entry point that replaced bootstrapLavaan() 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(), and ss_power_R2_sensitivity()) no longer accept it, so a misspelled or retired argument such as save = TRUE now stops with an error instead of being swallowed. ss_aipe_cv() with assurance supplied reports its noncentral accuracy note once, with the combined count, where it used to report it twice; and ss_aipe_cv_sensitivity() and ss_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 inside stats::poly(), and its no-fit message for the polynomial now counts occasions instead of suggesting start, which the polynomial rejects.
  • The equivalence sensitivity siblings speak their parents' language: ss_aipe_equivalence_smd_sensitivity() takes delta_lower / delta_upper and ss_aipe_equivalence_r_sensitivity() takes rho_lower / rho_upper, positive magnitudes with the upper bound required and the lower defaulting to symmetric, exactly as in equivalence_smd() and equivalence_r(). The signed equivalence_lower / equivalence_upper spellings, 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_expected and reports the expected full width: ss_aipe_equivalence_smd() and ss_aipe_mixed_effects() previously reported the half-width as ci_half_width_expected while ss_aipe_equivalence_r() reported the full width, a trap for anyone extracting the row programmatically.
  • The equivalence trio attaches the conf_level attribute the ci_* family always carried, and the equivalence_c() verdict label is spelled "Noninferior only", matching the solid noninferior the 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() and convert_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, and convert_z_normal()), with domain checks where a map's algebra ends (an R2 at 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 reliability and reliability_by_occasion can drift from the realized variance ratio when random variances are large, and document the schedule attribute; 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_change now 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, and ci_tukey_kramer replace dunnett_ci, scheffe_ci, games_howell_ci, and tukey_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, so ci_nc_t(), ci_nc_F(), and ci_nc_chisq() replace conf_limits_nct(), conf_limits_ncf(), and conf_limits_nc_chisq() (the snake-cased descendants of MBESS's conf.limits.nct() and kin), and moments_nc_t() and moments_nc_F() replace moments_nct() and moments_ncf() to match moments_nc_chisq(). The intervals join the ci_* 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. Splitting nc from the distribution token retires the one inherited exception (nct, ncf against nc_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-heritage ci_cc(), with the estimate row renamed from est_cor to r), and ci_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 in R/ci_correlation.R and share the ci_correlation help page.
  • Kish's design effect function is design_effect(); the abbreviation deft() is gone as a function name, while the returned table keeps its design_effect and deft rows, 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() and convert_Z_r() only (the lowercase spellings are gone) and the prose and math were swept to match. The limits of agreement function is limits_of_agreement(), with loa() kept as its short alias and bland_altman_loa() gone (the method is named for what it computes; Bland and Altman are credited in the references). reliability_omega_categorical() and covmat_from_cfa() are the only names for those functions; the reliability_omega_c() and covmat_from_cfm() aliases are gone. The dataset alias bindings HS_Data and Prime_Time are gone as well: every dataset carries exactly one name, the documented snake_case one, and unlike the alias bindings the canonical names work with data().

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), n counts units, and the former group column is population, one level per data generating parameter vector.
  • Measurement schedules can now be unit-specific, in every simulator: in place of a shared target_times grid, time_range = c(lower, upper) draws each unit's own measurement times uniformly between the bounds, with occasions fixing the number of times per unit or c(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 reach P + 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 and nlme::nlme() for the nonlinear curves started at the two-stage estimates, so sd_units becomes a variance component purged of estimation noise. The help page positions the function candidly against nlme::lmList(), nlme::nlsList(), and the self-starting SS* curves: what it adds is the landmark parameterizations, the simulator match, and one tidy interface across linear and nonlinear change. With a single trajectory (or id = 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 the n_used attribute; the full matrix of unit-level estimates rides along for plotting or as starting values for a simultaneous nlme::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 feeds plot_trajectories() and nonlinear mixed-model fitters: simulate_longitudinal_negative_exponential() (asymptotic regression), simulate_longitudinal_logistic(), simulate_longitudinal_gompertz(), and simulate_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(), and equivalence_c() replace tost_smd(), tost_r(), and tost_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 standard p_tost term. 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 interval equivalence_r() and ci_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 sibling ss_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_bdi with its wait list control, the studentized range procedures on test_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

CRAN checks
13OK
Slowest check: 15.7 min · r-oldrel-windows-x86_64
Status changes
  • OK13 OKNow
  • OK5 OK2026-09-22
Advisories

none known

Documentation

In release 1.0.0
READMEYes · 1,682 wordsVignettesYes · 18 · staticNEWSYes · 67% structured · mentions 1.0.0Citation fileYes · cites a publicationWebsiteYes · pkgdown
Cites a JSS article
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%

Downloads

627
CRAN downloads in the past year
Rank #20,972 · ~2/day · ~52/mo
Daily download trend is not available in this view yet.
62730 days
62790 days
6271 year
Compare downloads with other packages →
Also on5 r2u1 autocran

Repository

1Stars
1Forks
0Open issues
0Open PRs
1Releases
40Commits
1Commit identities
40 commits · Last activity 2026-10-15 · Default branch at 1.0.1, ahead of CRAN 1.0.0 (checked 2026-10-18)
Responsiveness
not measured

Forks over time

2026-09-22 · 02026-09-24 · 1
PracticesBeta

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.

Continuous integration (2)
GitHub ActionsR CMD check workflow

The R CMD check workflow runs on Linux, macOS and Windows, and on R-devel

Docs source (4)
README.Rmdpkgdown

GitHub Pages site last deployed 2026-10-15 · The repository has a site deploy workflow

pkgdown site last built 2026-10-15

Reproducibility and dev environment (1)
data-raw/
CRAN release process (1)
cran-comments.md
Show all practicesHide 2 practices
Research and citation (2)
CITATION.cffZenodo
Lint, format, editor (1)
RStudio project
How this is detected·Detection ruleset v3 (2026-09-26)

Dependencies

Declared dependencies
15 external dependencies (excludes base and recommended)

Installing DMAR adds 2 packages (0 with compiled code, 148 KB of source tarballs). Heaviest: withr 102 KB, generics 46 KB.

Depends (1)
R >= 4.0.0
Imports (7)
grDevicesMASSgenericsparallelstatsutilswithr
LinkingTo (0)
none
Enhances (0)
none
Reverse dependencies
0direct
0indirect

Nothing depends on this yet.

Datasets

People & History

People (1)
Author, Maintainer since 1.0.0 (2026)
Releases (1)
  • 1.0.0Latest
    2026-09-21 · current release
  • R
    R 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.

APA

Balamuta, J. J. (2026). R Observatory: Metrics for DMAR version 1.0.0 [Data set]. HJJB, LLC. Data release v2026-10-20. https://doi.org/10.5281/zenodo.21843040

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.

Report a problem with this page →

Privacy choices

These apply to this browser and are stored on this device only. Nothing about your choice is sent to us.

Read the privacy policy