compute_ltg_smd: Compute the LTG-SMD and related effect-size estimates

View source: R/compute_ltg_smd.R

compute_ltg_smdR Documentation

Compute the LTG-SMD and related effect-size estimates

Description

Computes the latent true-score and target-population anchored geometric standardized mean difference (LTG-SMD) along with conventional comparators: Hedges's g, Welch-type SMD, observed geometric SMD (within study), and external observed geometric SMD (in the reference sample).

Usage

compute_ltg_smd(
  study_data,
  reference_data,
  group_var,
  score_var = NULL,
  items = NULL,
  group_levels = NULL,
  reliability_estimator = "alpha",
  rho_external = NULL,
  se_method = c("fourth_moment", "normal"),
  verbose = FALSE
)

Arguments

study_data

A data frame containing the study sample, with one row per participant.

reference_data

A data frame containing the reference sample. May be the same as study_data if an internal (holdout) reference is used; see Section 8.2 of the paper.

group_var

Character. Name of the grouping variable in both data frames.

score_var

Character. Name of the precomputed composite score variable. If NULL, the composite is built by averaging the items in items.

items

Optional character vector of item names. Required if score_var is NULL, or if reliability is to be estimated from item- level data.

group_levels

Named character vector with names "reference" (group 0) and "focal" (group 1) specifying the levels of group_var. If NULL, the two unique values are sorted alphabetically with the first taken as reference.

reliability_estimator

Either the string "alpha" (default; uses coef_alpha()) or a function taking a matrix/data frame of items and returning a numeric scalar in (0, 1]. Custom estimators allow plugging in psych::omega(), CFA-based reliability, or any user-supplied procedure.

rho_external

Optional named numeric vector with names "focal" and "reference" specifying externally supplied reliability estimates. If provided, these override the internal estimator. Each value must lie in (0, 1].

se_method

Character. "fourth_moment" (default; uses sample fourth moments as described in Section 4.2 and Supplementary Section C of the paper) or "normal" (uses the simpler 2*sigma^4/(m-1) approximation that is valid under normality).

verbose

Logical. If TRUE, prints intermediate quantities.

Details

The LTG-SMD estimand (Section 2.3 of the companion paper) is

\delta_{\mathrm{LTG}} = \frac{\mu_{T1} - \mu_{T0}} {(\sigma^2_{T1,R}\sigma^2_{T0,R})^{1/4}}

where \mu_{Tg} are true-score means and \sigma^2_{Tg,R} are group-specific true-score variances in the target reference population R. The plug-in estimator substitutes observed study-sample means for the true-score means (assuming \mu_{Yg} = \mu_{Tg}) and reference-sample reliabilities times reference-sample observed variances for the true-score variances.

Hedges's small-sample correction factor J(N) = 1 - 3/(4N - 9) is applied to the conventional Hedges's g estimate but not to the LTG-SMD or to the observed geometric SMDs, consistent with conventional practice.

The analytic SE under se_method = "fourth_moment" uses \widehat{\mathrm{Var}}(s^2) = (\hat\mu_4 - \frac{m-3}{m-1}(s^2)^2)/m, which is consistent under arbitrary distributions of the score with finite fourth moments and reduces to the normal-theory approximation 2\sigma^4/(m-1) when the score is normal. Reliability is treated as fixed at its point estimate (the reliability-fixed approximation of Section 4.2); a reliability-propagated alternative is implemented by the bootstrap in ltg_smd_ci().

Value

An object of class "ltg_smd" containing:

point

Numeric. The LTG-SMD point estimate.

se_analytic

Numeric. The analytic delta-method standard error (reliability-fixed approximation; see Section 4.2).

se_method

Character. Which SE method was used.

estimates

Numeric vector with elements hedges_g, welch_smd, observed_geometric, external_observed, ltg_smd.

study

Data frame of group-level study-sample statistics.

reference

Data frame of group-level reference-sample statistics.

c_g

Numeric vector of length 2: study-to-reference SD ratios (c_focal, c_reference).

rho_g

Numeric vector of length 2: reliability estimates (rho_focal, rho_reference) in the reference sample.

factors

Named numeric vector with reliability_factor, study_to_target_factor, predicted_ratio_observed_to_LTG.

call

The matched call.

Examples

set.seed(2026)
gen_items <- function(n, shift = 0) {
  true <- rnorm(n)
  data.frame(
    item1 = true + rnorm(n, sd = 0.6) + shift,
    item2 = true + rnorm(n, sd = 0.6) + shift,
    item3 = true + rnorm(n, sd = 0.6) + shift,
    item4 = true + rnorm(n, sd = 0.6) + shift
  )
}
study_df <- rbind(
  cbind(condition = "control",   gen_items(15)),
  cbind(condition = "treatment", gen_items(15, shift = 0.5))
)
reference_df <- rbind(
  cbind(condition = "control",   gen_items(30)),
  cbind(condition = "treatment", gen_items(30, shift = 0.5))
)

result <- compute_ltg_smd(
  study_data     = study_df,
  reference_data = reference_df,
  group_var      = "condition",
  items          = c("item1", "item2", "item3", "item4"),
  group_levels   = c(reference = "control", focal = "treatment")
)
print(result)

# Custom reliability estimator: use psych::omega instead of alpha
# (illustrated on a larger synthetic sample, since omega needs more
# data than alpha to fit stably)
if (requireNamespace("psych", quietly = TRUE)) {
  gen_items6 <- function(n, shift = 0) {
    true <- rnorm(n)
    items <- as.data.frame(replicate(6, true + rnorm(n, sd = 0.6),
                                      simplify = FALSE))
    names(items) <- paste0("item", 1:6)
    items[] <- lapply(items, `+`, shift)
    items
  }
  study_big <- rbind(
    cbind(condition = "control",   gen_items6(60)),
    cbind(condition = "treatment", gen_items6(60, shift = 0.5))
  )
  reference_big <- rbind(
    cbind(condition = "control",   gen_items6(100)),
    cbind(condition = "treatment", gen_items6(100, shift = 0.5))
  )
  my_omega <- function(items) psych::omega(items, plot = FALSE)$omega.tot
  result_omega <- compute_ltg_smd(
    study_big, reference_big,
    group_var = "condition",
    items = paste0("item", 1:6),
    reliability_estimator = my_omega,
    group_levels = c(reference = "control", focal = "treatment")
  )
  print(result_omega)
}

ltgsmd documentation built on Sept. 27, 2026, 5:07 p.m.