Skip to content

Simulating an ACE dose response

Blazej Mrozinski edited this page Jul 2, 2026 · 1 revision

Simulating an ACE dose-response (the cost of binning)

One of the most common things done to an ACE score is to bin it: into Webster's 0 / 1 / 2-3 / 4+ categories, or into the clinical "four or more" dichotomy. Binning throws away information, and sim_ace_dose() lets you measure exactly how much. It generates an ACE count that carries a true linear dose-response into a continuous outcome, so you can compare analyzing the count as it is against binning it.

sim_ace_dose()

sim_ace_dose(n, slope = 0, k = 10, rho = 0.30, p_items = NULL, sigma = 1)
Argument What it is
n Sample size.
slope The true linear effect of the ACE count on the outcome. 0 is the null.
k, rho, p_items The ACE-count generator, exactly as in sim_symptoms().
sigma Residual standard deviation of the outcome.

It returns a data frame with the continuous ace, two binned codings (ace_bin as a 1 to 4 integer, ace_fac as a factor), and the outcome y.

library(countkit)
set.seed(2)
d <- sim_ace_dose(n = 300, slope = 0.07, k = 10)

# analyze the count as it is
summary(lm(y ~ ace, d))$coefficients["ace", c("Estimate", "Pr(>|t|)")]
#>  Estimate  Pr(>|t|)
#>    0.0826    0.0200

# bin it to the clinical "four or more" threshold
d$ge4 <- as.integer(d$ace >= 4)
summary(lm(y ~ ge4, d))$coefficients["ge4", c("Estimate", "Pr(>|t|)")]
#>  Estimate  Pr(>|t|)
#>    0.2512    0.1432

Same data, same underlying effect. Keeping the count continuous recovers the slope and detects the effect (p = .02). Collapsing it to "four or more" loses so much information that the same effect no longer reaches significance (p = .14). The dose-response curve that clinical thresholds rest on is partly an artifact of how the score is coded, and this is the demonstration that shows it. If you want the gradient, keep the count.

Clone this wiki locally