-
Notifications
You must be signed in to change notification settings - Fork 0
diagnose
diagnose() looks at a vector of counts and tells you three things that decide how
to model it: whether it is overdispersed, whether it is bounded out of a fixed
number of trials, and whether it has more zeros than its own dispersion explains.
It then names the model family those signals imply. It does not fit the model for
you; it hands you the diagnosis and points at the right shelf.
diagnose(x, k = NULL, group = NULL)| Argument | What it is |
|---|---|
x |
A non-negative integer vector, your count outcome. NAs are dropped. |
k |
The ceiling, if the count is "how many out of k" (items endorsed, questions correct). Leave it NULL for open-ended counts. |
group |
The design's condition factor, if the counts come from more than one group. Pass it so the dispersion test looks at variation within groups, not the spread created by a real group difference. |
It returns a count_diagnosis object with a print method. The fields (vmr,
prop_zero, bounded, dispersion_p_over, rec_code, and the rest) are all
readable if you want to branch on them in code.
An adverse-childhood-experience score is how many of ten items a person endorses. Because it is bounded, the right home is the binomial family, not Poisson.
library(countkit)
set.seed(1)
ace <- sim_symptoms(n = 500, effect = 0, k = 10)$ace
diagnose(ace, k = 10)
#> Count diagnosis (n = 1000)
#> mean = 1.53, var = 2.68, variance-to-mean ratio = 1.74
#> zeros observed = 31.7% (Poisson predicts 21.5%; fitted NB predicts 31.8%)
#> max = 8 (ceiling k = 10, bounded)
#> dispersion ratio = 1.74 (overdispersion p < .001; underdispersion p = 1.000)
#> >> Recommended: bounded-of-k -> binomial GLM with a dispersion check;
#> beta-binomial or quasi-binomial under extra-binomial variationTwo things to read here. Because you passed k = 10, the tool sees the ceiling and
routes to the binomial family. And look at the zero line: a third of the scores are
zero, far past the 21.5% a Poisson would predict, but a fitted negative binomial
expects almost exactly that many (31.8%). So the zeros are just what overdispersion
produces, not a separate "never happened" process, and the tool does not falsely
flag zero-inflation.
Fluency counts have no ceiling and are overdispersed. The tool sends them to the negative binomial.
set.seed(2)
fl <- sim_fluency(n = 300, effect = 0, mu = 15, vmr = 4)$y
diagnose(fl)
#> Count diagnosis (n = 600)
#> mean = 14.99, var = 62.79, variance-to-mean ratio = 4.19
#> zeros observed = 0.0% (Poisson predicts 0.0%; fitted NB predicts 0.1%)
#> max = 46
#> dispersion ratio = 4.18 (overdispersion p < .001; underdispersion p = 1.000)
#> >> Recommended: overdispersed -> negative binomial (Poisson SEs will be too small)This is the argument people forget, and it is the one that keeps the tool honest.
If your counts come from two groups with genuinely different means, pooling them
makes the outcome look overdispersed even when it is perfectly Poisson inside each
group. Pass group and the dispersion test conditions on the group means.
set.seed(4)
d <- sim_fluency(n = 500, effect = log(2), mu = 15, vmr = 1) # Poisson within group
diagnose(d$y) # pooled: fooled
#> variance-to-mean ratio = 3.57
#> dispersion ratio = 3.57 (overdispersion p < .001; underdispersion p = 1.000)
#> >> Recommended: overdispersed -> negative binomial (Poisson SEs will be too small)
diagnose(d$y, group = d$group) # conditional: not fooled
#> dispersion ratio = 0.99 (overdispersion p = .599; underdispersion p = .401)
#> >> Recommended: ~equidispersed, high mean -> Poisson fine; Gaussian approx. often acceptableSame data, opposite advice. The pooled call sees a variance-to-mean ratio of 3.57 and says negative binomial; the conditional call sees that, within groups, the ratio is 0.99 and correctly says the counts are Poisson. Whenever you have a design, pass the design.
The rec_code field carries a short machine-readable tag, so you can branch on the
recommendation in code:
rec_code |
When | Points to |
|---|---|---|
betabinom |
Bounded out of k, with extra-binomial variance |
Beta-binomial or quasi-binomial |
zi_binomial |
Bounded and genuinely zero-inflated | Zero-inflated binomial or beta-binomial hurdle |
nb |
Open-ended and overdispersed | Negative binomial |
qpois |
Underdispersed (variance below the mean) | Quasi-Poisson or Conway-Maxwell-Poisson |
hurdle |
More zeros than a negative binomial predicts | Hurdle or zero-inflated model |
poisson |
Equidispersed | Poisson (a Gaussian approximation is often fine at high means) |
The tool stops at the recommendation. Fitting the model it points to, and reporting
coverage rather than only a p value, is the next step, and it is one line in each
case (for example MASS::glm.nb(y ~ group) for the negative binomial).
Simulate a task