--- title: "How DMAR's Functions Fit Together: A Deep Dive" author: "Ken Kelley" date: "September 2026" output: rmarkdown::html_vignette: toc: true toc_depth: 3 vignette: > %\VignetteIndexEntry{How DMAR's Functions Fit Together: A Deep Dive} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ## Why This Vignette Exists DMAR has grown to encompass several large families of functions: effect size point estimates, exact-noncentral distribution confidence intervals, asymptotic-variance utilities, design-stage expected-value calculators, accuracy in parameter estimation (AIPE) sample size planners, reliability coefficients, and agreement / multivariate measures. Each function is documented in isolation, but the package's value is in how the functions *compose*. This vignette walks through the package's architecture from the user's perspective and shows the five high-traffic composition patterns. ## The Four Building Blocks For any single population quantity \(\theta\) the package supports four operations: ``` point estimate sample size noncentral CI asymptotic / variance planning building blocks ┌──────────────┐ ┌──────────────────┐ ┌───────────────────┐ ┌─────────────────┐ \(\theta\) → │ smd, omega², r│ → │ ss_aipe_smd, │ → │ ci_smd, ci_r, │ ← │ var_smd, var_r, │ │ R², icc, ... │ │ ss_aipe_R2, ... │ │ ci_omega_squared, │ │ var_omega_squared│ └──────────────┘ └──────────────────┘ │ ci_R2, ... │ │ ... │ ↑ ↑ └───────────────────┘ ↑ │ │ │ │ │ │ │ │ │ ┌──────┴─────────────┐ │ │ │ │ expected_smd, │ │ │ │ │ expected_r, │ ────────┘ │ │ │ expected_R2 ... │ │ │ └────────────────────┘ │ │ │ └──────────────── transforms of each other ─────────────────────────────┘ (smd ↔ cles ↔ proportion_of_superiority ↔ nnt_from_smd; r ↔ partial_r) ``` The four columns are tightly coupled: every AIPE planner is built from a variance utility; every CI is built from a noncentral distribution; every expected-value function is the design-stage analog of an estimator. Once you internalize the layout, asking "what is the recommended workflow for quantity X" reduces to asking "which row of X's variance / CI / expected value / AIPE planner do I need." ## 1. Variance Utility → AIPE Planner The most pervasive composition is `var_*` feeding `ss_aipe_*`. For any quantity \(\theta\) with a known asymptotic variance \(\mathrm{Var}(\hat\theta \mid \theta, n)\), the AIPE planner solves for the smallest \(n\) such that $$ z_{1-\alpha/2} \cdot \sqrt{\mathrm{Var}(\hat\theta \mid \theta, n)} \le w/2, $$ where \(w\) is the target full width of the CI. The AIPE framework, planning for a sufficiently narrow confidence interval rather than for power, is developed in Kelley and Maxwell (2003) and Maxwell, Kelley, and Rausch (2008); see also Maxwell, Delaney, and Kelley (2027) for the model comparison treatment. Concretely: ``` r # SMD (Cohen's d): var_smd → ss_aipe_smd # Pearson r (J = 0): var_r → ss_aipe_partial_r (J = 1, simple case) # Partial r: var_partial_r → ss_aipe_partial_r # Semipartial r: var_semipartial_r → ss_aipe_semipartial_r # Squared multi R: var_R2 → ss_aipe_R2 # Cliff's delta: (max-variance bound) → ss_aipe_cliff_delta # omega²: var_omega_squared → ss_aipe_omega_squared (noncentral F) # Cronbach alpha: var_alpha → ss_aipe_reliability # ICC: var_icc → ss_aipe_icc # CV: var_cv → ss_aipe_cv # Indirect effect ab: var_indirect_effect → ss_aipe_indirect_effect ``` This pairing is the package's most common usage pattern. The variance utility is the design-stage primitive; the AIPE planner is the inverse, returning the \(n\) that achieves a target precision. ### Worked Example: Pearson r We plan a study where we expect \(\rho \approx 0.30\) and want a 95% CI of full width 0.20. ``` r # Step 1: ask the variance utility for the sampling variance at a candidate n. var_r(rho = 0.30, n = 100) ``` |term |value | |:------------|:-------| |var_r_normal |0.00836 | |var_fisher_z |0.0103 | ``` r # Step 2: the AIPE planner inverts the same family of formulas to give # the n needed for the target width. DMAR has no zero-order Pearson-r # planner; the partial-r planner at J = 1 is the simple-correlation case. ss_aipe_partial_r(rho = 0.30, J = 1, width = 0.20) ``` |term |value | |:--------------|:-----| |necessary_N |321 | |expected_width |0.2 | |rho |0.3 | |J |1 | |width_target |0.2 | |conf_level |0.95 | Confidence level: 95% Both sides use the same normal-theory \((1 - \rho^2)^2\) variance family (Fisher, 1915; Olkin & Finn, 1995), differing only by an off-by-one in the denominator degrees of freedom (\(n - 1\) for `var_r()`, \(n - J - 1\) for the planner), so the planner's output is consistent with what `var_r()` returns at that recommended \(n\). ## 2. Expected-Value Function → Design-Stage Substitution For estimators with non-trivial bias, the package provides `expected_*()` functions that report \(\mathrm{E}[\hat\theta \mid \theta, n]\) and the size of the bias. These are useful in two situations: 1. **Reporting:** at the analysis stage, the difference between \(\hat\theta\) and \(\mathrm{E}[\hat\theta]\) tells the analyst how much of the observed value is bias. 2. **Design-stage planning:** when a sample size planner takes \(\theta\) as input but the realized data will yield a biased sample \(\hat\theta\), substituting \(\mathrm{E}[\hat\theta]\) in place of \(\theta\) corrects the planner's prediction. The package's expected-value functions are: | Quantity | Bias | Helper | |---------------------------|---------|-------------------------| | Pearson \(r\) | downward (small \(n\)) | `expected_r()` | | Partial \(r\) | downward (grows with \(J\)) | `expected_partial_r()` | | Squared multi \(R^2\) | upward (always) | `expected_R2()` | | Cohen's \(d\) | upward (small \(n\)) | `expected_smd()` | ### Worked Example: The Standardized Mean Difference ``` r # Population delta = 0.4, planned n = 40 per group. # Naive planning assumes the observed d will average 0.40; in fact # the sample d will average slightly larger. expected_smd(delta = 0.4, n_1 = 40) ``` |delta |n_1 |n_2 |expected_smd |bias |j_correction | |:-----|:---|:---|:------------|:------|:------------| |0.4 |40 |40 |0.404 |0.0039 |0.99 | The reported `j_correction` is the Hedges (1981) factor \(J(\mathit{df})\) that maps Cohen's \(d\) to Hedges' \(g\). The same factor is applied internally by `smd(..., unbiased = TRUE)`, which returns the bias-corrected estimate \(g = J(\mathit{df})\,d\), so the same constant runs throughout the \(d\)-family of functions for consistency. ## 3. Effect Size Transforms: `smd` ↔ `cles` ↔ `proportion_of_superiority` ↔ `nnt` A single standardized mean difference (Cohen's \(d\)) can be reported on five common scales without losing information: | Scale | Formula | Function in DMAR | |--------------------------------------|--------------------------------------|---------------------------| | Standardized mean difference | \(d\) | `smd()`, `ci_smd()` | | Proportion of superiority (Cohen's \(U_3\)) | \(\Phi(d)\) | `proportion_of_superiority()` | | Common language (independent groups) | \(\Phi(d / \sqrt 2)\) | `cles()` | | Success-rate difference | \(2 \Phi(d / \sqrt 2) - 1\) | (intermediate) | | Number needed to treat | \(1 / [2 \Phi(d / \sqrt 2) - 1]\) | `nnt_from_smd()` | Each downstream function accepts either a point estimate of \(d\) or the same plus group sizes for an exact noncentral \(t\) CI, and propagates the CI bounds through the monotone transform. Because the transforms are monotone, the coverage probability is preserved exactly (no extra approximation is introduced). ### Walked Example at Three Reference d Values ``` r for (d in c(0.2, 0.5, 0.8)) { cat(sprintf( "d = %.1f -> PS = %.2f CLES = %.2f NNT = %.1f\n", d, proportion_of_superiority(d)$value[2], cles(d)$value[2], nnt_from_smd(d)$value[3] )) } #> d = 0.2 -> PS = 0.58 CLES = 0.56 NNT = 8.9 #> d = 0.5 -> PS = 0.69 CLES = 0.64 NNT = 3.6 #> d = 0.8 -> PS = 0.79 CLES = 0.71 NNT = 2.3 ``` For an applied report, the same effect can be communicated on whichever scale is most natural for the audience without recomputing anything. ## 4. Ordinal Alternatives: `cliff_delta`, `vargha_delaney_A`, `probability_of_superiority_paired` When the dependent variable is ordinal, skewed, or you want a nonparametric effect size, the same role is played by U-statistic estimators: | Independent groups | Function | |---------------------------|-----------------------------------------| | Probability of superiority| `cles()` (under bivariate normality) | | Stochastic dominance | `cliff_delta()` (ordinal, U-statistic) | | | Vargha-Delaney \(A = (\delta + 1)/2\), `vargha_delaney_A()` | | Paired data | `probability_of_superiority_paired()` | Each returns an analytic CI; `cliff_delta()` uses the Cliff (1996) U-statistic variance, and `probability_of_superiority_paired()` uses the Brunner-Munzel (2000) within-pair variance, all with a Fisher-style \(\arctanh\) transformation so the bounds stay in \([-1, 1]\) (for \(\delta\)) or \([0, 1]\) (for \(P_S\)). ## 5. Reliability Composition The reliability family follows the same four-block pattern but with one extra wrinkle: alpha is the workhorse, omega is the modern default, and \(H\) is the upper bound that sets the ceiling of what is achievable with the same indicators: ``` r # Point estimate: reliability_alpha(), reliability_omega(), reliability_H() # CI: reliability() (general wrapper) # Asymptotic variance: var_alpha() # Design-stage AIPE: ss_aipe_reliability() ``` \(H\) is uniformly \(\ge \omega \ge \alpha\) for unidimensional indicators; if `reliability_H()` is far larger than `reliability_alpha()`, the equally weighted composite is wasting reliability that an optimally weighted composite would capture. ## 6. The Mediation Pipeline For a simple three-variable mediation model \(X \to M \to Y\) with indirect effect \(ab\): ``` r # Asymptotic variance: var_indirect_effect(a, b, var_a, var_b, cov_ab) # - returns Sobel, Aroian, Goodman, and second-order delta variances. # AIPE planning: ss_aipe_indirect_effect(a, b, width, method) # - method = "closed_form": the delta method (Sobel, 1982) width # - method = "monte_carlo": the Monte Carlo interval width, simulated # at each candidate n (Tofighi & MacKinnon, 2011) ``` The two methods correspond to the two main approaches in the mediation literature; `var_indirect_effect()` makes the underlying SE formulas explicit so the user can see what the planner is solving against. ## 7. Multivariate and Agreement Utilities The package's measurement family is small but covers the common needs: - `lin_ccc()`: Lin's (1989) concordance correlation, with the CI built on Lin's *z*-transformed standard error. - `loa()`: Bland-Altman 95% limits of agreement with the Carkeet (2015) exact tolerance-factor CIs, by default for the limits considered as a pair (his recommended construction), with the per-limit noncentral *t* form as `method = "individual"`. - `variance_components_mls()`: Burdick-Graybill (1992) modified-large- sample CIs on variance components, the standard tool in generalizability theory (Brennan, 2001). - `ci_eigenvalue()`: log-scale CI on a sample eigenvalue under the Anderson (2003) asymptotic distribution. - `procrustes_phi()`: Tucker's congruence coefficient with permutation significance test (Lorenzo-Seva & ten Berge, 2006). These are stand-alone utilities; they do not feed into AIPE planners yet, although the variance components implied by `variance_components_mls()` do compose with `var_icc()` and `ss_aipe_icc()` for generalizability- theory planning. ## Argument-Name Conventions When using multiple DMAR functions in a single pipeline, the argument-name conventions are worth knowing: | Quantity | Argument name(s) | |--------------------------------|-------------------------------| | Population correlation | `rho` (Greek; new code) | | Sample correlation | `r` (Roman; existing code) | | Population SMD | `delta` | | Sample SMD | `smd` | | Group sample sizes | `n_1`, `n_2` | | Total sample size | `n` (single-sample), `N` (some legacy)| | Number of controls (partial r) | `J` | | Number of items | `p_items` | | Number of predictors | `p` | | Number of raters (ICC) | `k` | | Effect df / error df | `df_effect`, `df_error` | | Target CI width | `width` | | Which-width specifier | `which_width` ∈ {"Full", "Lower", "Upper"} | | Confidence level | `conf_level` | | Per-tail alphas | `alpha_lower`, `alpha_upper` | | Coverage assurance probability | `assurance` (in `(0.5, 1)`) | Pattern: lower-case Greek letters denote population values (`rho`, `delta`, `alpha`); Roman letters denote sample estimators (`r`, `smd`). When in doubt, the function's `@param` line in the help file is explicit about which is wanted. ## Two Consistent Return Shapes DMAR functions return one of two tidy data-frame shapes: 1. **Long form: `data.frame(term, value)`**: used by all variance utilities, AIPE planners, effect size point estimates, and CI helpers. The `term` column names the quantity; `value` is the numeric value. 2. **Wide form: one row, many columns**: used by `omega_squared()`, `eta_squared_partial()`, and similar effect size functions that return one row per *effect* in a factorial design (with columns `effect`, `omega_squared`, `F_value`, `df_effect`, `df_error`, `N`). Pipeline code can use `dplyr::filter(term == "...")` for the long form or column-access for the wide form. The two shapes compose: the wide form can always be reshaped to long with `tidyr::pivot_longer()`. ## Recommended Workflows ### A. Reporting a Standardized Mean Difference ``` r set.seed(113) g1 <- rnorm(50, mean = 0, sd = 1) g2 <- rnorm(50, mean = 0.5, sd = 1) # 1. Point estimate (biased d and Hedges' g): smd(group_1 = g1, group_2 = g2) # d smd(group_1 = g1, group_2 = g2, unbiased = TRUE) # g # 2. CI on the standardized mean difference (Cohen's d): ci_smd(ncp = t.test(g1, g2, var.equal = TRUE)$statistic, n_1 = 50, n_2 = 50) # 3. Alternative effect size scales: cles(smd = 0.5, n_1 = 50, n_2 = 50) # probability of superiority proportion_of_superiority(smd = 0.5, n_1 = 50, n_2 = 50) # proportion above ctrl mean nnt_from_smd(smd = 0.5, n_1 = 50, n_2 = 50) # number-needed-to-treat # 4. Variance (for meta-analytic weighting): var_smd(delta = 0.5, n_1 = 50, n_2 = 50) ``` ### B. Planning a Partial Correlation Study ``` r # Anticipated partial r = 0.30, 3 controls, target 95% CI width = 0.20. # 1. AIPE planner (raw-scale Olkin-Finn variance): ss_aipe_partial_r(rho = 0.30, J = 3, width = 0.20) # 2. Same plan on the Fisher's Z scale (Bonett 2008): ss_aipe_partial_r(rho = 0.30, J = 3, width = 0.20, fisher_z = TRUE) # 3. Variance utility: what SE would result at the recommended n? var_partial_r(r = 0.30, n = 80, J = 3) # 4. Design-stage bias estimate: what r should we expect to observe? expected_partial_r(rho = 0.30, n = 80, J = 3) ``` ### C. Planning an Omega Squared CI ``` r # 3-group one-way ANOVA, anticipated omega² = 0.10, target full width 0.10. ss_aipe_omega_squared(population_omega_squared = 0.10, df_effect = 2, width = 0.10) # Confirm: at that n, what does ci_omega_squared() actually return? N <- ss_aipe_omega_squared(0.10, df_effect = 2, width = 0.10 )$value[1] F_val <- 1 + 0.10 * N / (2 * 0.90) ci_omega_squared(F_value = F_val, df_effect = 2, df_error = N - 3, N = N) ``` ### D. Reporting an Indirect (Mediated) Effect ``` r # After fitting the X -> M and Y ~ X + M regressions: a_hat <- 0.40; b_hat <- 0.40 var_a <- 0.02; var_b <- 0.02 # All four variance formulas in one call: var_indirect_effect(a = a_hat, b = b_hat, var_a = var_a, var_b = var_b) # Plan an n for the next study: ss_aipe_indirect_effect(a = 0.40, b = 0.40, width = 0.20, method = "closed_form") ``` ### E. Two-Method Agreement Study ``` r set.seed(113) method_a <- rnorm(40, mean = 100, sd = 15) method_b <- method_a + rnorm(40, mean = 2, sd = 5) # 1. Lin's concordance correlation with CI: lin_ccc(method_a, method_b) # 2. Bland-Altman 95% limits of agreement with CIs on the limits: loa(method_a, method_b) # 3. Cohen's U3 / CLES interpretation if a method comparison can be # framed as a "difference": d_estimate <- mean(method_b - method_a) / sd(method_b - method_a) cles(smd = d_estimate) ``` ## Summary DMAR's architecture rests on four building blocks for any quantity \(\theta\): a point estimator with variance, an exact-noncentral CI, an expected-value function for design-stage planning, and an AIPE sample- size planner. The functions in each block compose horizontally (the same \(\theta\) shows up in all four) and vertically (within a block, related transforms like \(d \to \mathrm{CLES} \to U_3 \to \mathrm{NNT}\) are explicit). Knowing which block a given task lives in is half the battle; the function name and help file complete the picture.