Skip to contents

Compares the distribution of leading significant digits in x with Benford's law, \(P(d) = \log_{10}(1 + 1/d)\). Naturally occurring quantities that span several orders of magnitude follow it closely; figures that were rounded, truncated, capped, re-scaled, or invented typically do not. That makes it a cheap screen for a numeric column that arrived looking plausible but is not the measurement it claims to be.

It is a SCREEN, not a verdict. Columns with a narrow range, a unit floor or ceiling, or an assigned-identifier structure (postcodes, year fields, prices ending in 99) legitimately violate Benford's law. Treat a small p-value as a reason to look, never as evidence of fabrication.

Usage

benfordtst(x)

Arguments

x

Numeric vector; zero and non-finite values are dropped.

Value

A list of class bricklayer_benford with counts (observed digit frequencies 1–9), expected, proportion, statistic, df, p_value, logpvalue (the log of the upper tail, which keeps its information where p_value underflows to 0), and n (the number of values used). counts, expected and proportion are named numeric vectors with names "1" to "9". The print method shows the verdict and a bar chart of observed against expected shares.

Details

Zeros and non-finite values have no leading significant digit and are excluded; the sign is ignored.

With \(n\) usable values, \(O_d\) the count with leading digit \(d\) and \(E_d = n \log_{10}(1 + 1/d)\), $$X^2 = \sum_{d=1}^{9} \frac{(O_d - E_d)^2}{E_d}$$ on 8 degrees of freedom. The smallest Benford share is 0.046 (digit 9), so the chi-square approximation needs about \(n \ge 110\) for every expected count to reach 5; below that treat the p-value as rough. Digits are counted in compiled code in blocks of a million values, and a long vector shows a progress bar in an interactive session (silenced by options(morie.quiet = TRUE)). Errors: non-numeric input, or no finite non-zero value.

References

Benford F (1938). The law of anomalous numbers. Proceedings of the American Philosophical Society 78(4), 551–572.

See also

Examples

# A quantity spanning several orders of magnitude follows the law.
set.seed(3)
benfordtst(10^stats::runif(2000, 0, 6))
#> ╭── Benford first-digit screen ───────────────────────────────────────────╮
#> │   ✓ consistent with Benford's law                                       │
#> │                                                                         │
#> │   values used  2,000                                                    │
#> │   chi-square   10.073                                                   │
#> │   df           8                                                        │
#> │   p-value      0.260                                                    │
#> │                                                                         │
#> │   digit  observed  expected        shape                                │
#> │       1     0.298     0.301  ####################                       │
#> │       2     0.169     0.176  ###########                                │
#> │       3     0.126     0.125  ########                                   │
#> │       4     0.092     0.097  ######                                     │
#> │       5     0.073     0.079  #####                                      │
#> │       6     0.072     0.067  #####                                      │
#> │       7     0.054     0.058  ####                                       │
#> │       8     0.060     0.051  ####                                       │
#> │       9     0.055     0.046  ####                                       │
#> │                                                                         │
#> │   The leading digits are consistent with Benford's law (p = 0.260); the │
#> │   largest gap is at 9, 5.5% seen against 4.6% expected. Benford's law   │
#> │   expects a leading 1 about 30% of the time and a 9 under 5%. A         │
#> │   departure is a reason to look closer (rounding, thresholds, made-up   │
#> │   figures), never proof by itself.                                      │
#> ╰─────────────────────────────────────────────────────────────────────────╯

# Digits drawn uniformly do not.
benfordtst(as.numeric(paste0(sample(1:9, 2000, TRUE), "000")))
#> ╭── Benford first-digit screen ───────────────────────────────────────────╮
#> │   ! departs from Benford's law (screen only, not a verdict)             │
#> │                                                                         │
#> │   values used  2,000                                                    │
#> │   chi-square   769.038                                                  │
#> │   df           8                                                        │
#> │   p-value      < 0.001                                                  │
#> │                                                                         │
#> │   digit  observed  expected        shape                                │
#> │       1     0.106     0.301  #################                          │
#> │       2     0.123     0.176  ####################                       │
#> │       3     0.123     0.125  ####################                       │
#> │       4     0.112     0.097  ##################                         │
#> │       5     0.103     0.079  #################                          │
#> │       6     0.102     0.067  #################                          │
#> │       7     0.099     0.058  ################                           │
#> │       8     0.119     0.051  ###################                        │
#> │       9     0.112     0.046  ##################                         │
#> │                                                                         │
#> │   The leading digits depart from Benford's law (p < 0.001); the largest │
#> │   gap is at 1, 10.7% seen against 30.1% expected. Benford's law expects │
#> │   a leading 1 about 30% of the time and a 9 under 5%. A departure is a  │
#> │   reason to look closer (rounding, thresholds, made-up figures), never  │
#> │   proof by itself.                                                      │
#> ╰─────────────────────────────────────────────────────────────────────────╯

# The expected proportions are the closed form.
b <- benfordtst(10^stats::runif(500, 0, 5))
all.equal(unname(b$expected) / b$n, log10(1 + 1 / (1:9)))
#> [1] TRUE

# Zeros carry no leading digit and are excluded from n.
benfordtst(c(0, 0, 1, 2, 3))$n
#> [1] 3

try(benfordtst(c(0, NA)))
#> Error : `x` has no finite non-zero values to take a leading digit from