Tests whether the category counts of a new sample agree with a reference
distribution that is taken as known, such as proportions fixed by a
specification or a published breakdown. It is Pearson's chi-square
goodness-of-fit test. When the reference is itself a sample, use
drfthomog(), which accounts for the
reference's own sampling
error.
Value
A named length-4 numeric: statistic, df,
p_value and logpvalue, the natural log of the upper tail, which
keeps its information where p_value underflows to 0.
It has class c("rmbl_drftchisq", "rmbl_measure", "numeric"), so it
prints as a box with its inputs (kept in attribute "lakner");
arithmetic, [, c() and as.numeric() give plain
numbers.
Details
Pearson's chi-square goodness-of-fit statistic comparing observed
category counts with the proportions a capsule was pinned against. Use
it where drftks() cannot apply, because the
column is a factor or a set of codes rather than a number.
Categories present in one argument and not the other are aligned by name, so a vanished category registers as a shortfall against its expected count.
A category that OCCURS but which the reference gives probability zero
contradicts the pinned distribution outright, and its chi-square term is
unbounded; statistic is then Inf and p_value is
0. If a new category is a legitimate possibility rather than a
contradiction – which it usually is when the reference is itself a
finite sample – use
drfthomog() instead.
With \(O_j\) the observed counts and \(E_j = N e_j / \sum e\) the
reference scaled to the observed total \(N\),
$$X^2 = \sum_j \frac{(O_j - E_j)^2}{E_j}$$
over the categories with \(E_j > 0\), on \(k - 1\) degrees of freedom.
The p-value is the upper tail of the chi-square distribution, computed
directly (not as one minus the lower tail), so it does not round to zero
early. With a single category there is nothing to test: df is 0 and
both p-values are NA. The chi-square approximation is poor when
expected counts are below about 5;
stats::chisq.test() with
simulate.p.value = TRUE is an alternative there.
Errors: a numeric vector without names; negative, infinite or missing counts; a total of zero on either side.
See also
drfthomog(),
cpsdrft(),
stats::chisq.test() for the full test object.
Examples
ref <- c(a = 50, b = 30, c = 20)
# Counts matching the reference proportions: nothing to report.
drftchisq(c(a = 100, b = 60, c = 40), ref)
#> ╭── Chi-square test against a reference distribution ─────────────────────────╮
#> │ Counts 200 │
#> │ Categories 3 │
#> │ │
#> │ statistic value │
#> │ --------- ----- │
#> │ statistic 0 │
#> │ df 2 │
#> │ p_value 1.000 │
#> │ logpvalue 0 │
#> │ │
#> │ The counts agree with the reference distribution (p = 1.000, not below │
#> │ 0.05). │
#> │ │
#> │ The reference is taken as known; when it is itself a sample, │
#> │ drfthomog() allows for its own sampling error. │
#> ╰─────────────────────────────────────────────────────────────────────────────╯
# A reallocated mix is detected.
drftchisq(c(a = 40, b = 60, c = 100), ref)
#> ╭── Chi-square test against a reference distribution ─────────────────────────╮
#> │ Counts 200 │
#> │ Categories 3 │
#> │ │
#> │ statistic value │
#> │ --------- ------- │
#> │ statistic 126 │
#> │ df 2 │
#> │ p_value < 0.001 │
#> │ logpvalue -63 │
#> │ │
#> │ The counts depart from the reference distribution (p < 0.001, below │
#> │ 0.05). │
#> │ │
#> │ The reference is taken as known; when it is itself a sample, │
#> │ drfthomog() allows for its own sampling error. │
#> ╰─────────────────────────────────────────────────────────────────────────────╯
# Agrees with stats::chisq.test().
o <- c(a = 40, b = 60, c = 100)
all.equal(drftchisq(o, ref)[["statistic"]],
as.numeric(stats::chisq.test(o, p = ref / sum(ref))$statistic))
#> [1] TRUE
# Raw vectors are tabulated for you.
drftchisq(c("a", "a", "b", "b"), c("a", "b"))
#> ╭── Chi-square test against a reference distribution ─────────────────────────╮
#> │ Counts 4 │
#> │ Categories 2 │
#> │ │
#> │ statistic value │
#> │ --------- ----- │
#> │ statistic 0 │
#> │ df 1 │
#> │ p_value 1.000 │
#> │ logpvalue 0 │
#> │ │
#> │ The counts agree with the reference distribution (p = 1.000, not below │
#> │ 0.05). │
#> │ │
#> │ The reference is taken as known; when it is itself a sample, │
#> │ drfthomog() allows for its own sampling error. │
#> ╰─────────────────────────────────────────────────────────────────────────────╯
# A category the reference rules out, but which occurs, is a flat
# contradiction rather than a large finite statistic.
drftchisq(c("a", "a", "b", "d"), c("a", "a", "b", "b"))
#> ╭── Chi-square test against a reference distribution ─────────────────────────╮
#> │ Counts 4 │
#> │ Categories 3 │
#> │ │
#> │ statistic value │
#> │ --------- ------- │
#> │ statistic Inf │
#> │ df 1 │
#> │ p_value < 0.001 │
#> │ logpvalue -Inf │
#> │ │
#> │ A category the reference rules out occurs: a flat contradiction of the │
#> │ reference, not a large finite statistic. │
#> │ │
#> │ The reference is taken as known; when it is itself a sample, │
#> │ drfthomog() allows for its own sampling error. │
#> ╰─────────────────────────────────────────────────────────────────────────────╯
# When a new category is legitimate, compare two samples instead.
drfthomog(c("a", "a", "b", "b"), c("a", "a", "b", "d"))
#> ╭── Chi-square test of homogeneity ─────────────────────────────────────────╮
#> │ Samples 4 and 4 values │
#> │ Categories 3 │
#> │ Method Monte Carlo permutation (small expected counts) │
#> │ │
#> │ statistic value │
#> │ --------- ----- │
#> │ statistic 1.333 │
#> │ df 2 │
#> │ p_value 1.000 │
#> │ logpvalue 0 │
#> │ │
#> │ The two samples' mixes of categories agree (p = 1.000, not below 0.05). │
#> │ │
#> │ Both samples carry sampling error; with an expected count below 5 │
#> │ the p-value is a Monte Carlo one under a fixed seed. │
#> ╰───────────────────────────────────────────────────────────────────────────╯
