A change table over fifty institutions is fifty tests. Reporting the
raw p-values invites reading the largest of fifty noise draws as a
finding. This adds p_adjusted (Benjamini-Hochberg by default, which
controls the false discovery rate over the scan) and significant
at level alpha after adjustment. Exact p-values are computed where
the object does not carry them: the conditional binomial test for
yoy() counts and for rate_change()
(with the exposures as the
binomial weights).
Arguments
- x
An
rmbl_yoyorrmbl_rate_changeobject, or any data frame with ap_valuecolumn.- method
Character, default
"BH": any method ofp.adjust("BH","holm","bonferroni","BY","hochberg","hommel","fdr","none").- alpha
Number, default 0.05: the level at which
significantis decided, applied to the adjusted p-values.
Value
x with p_value (if it was missing),
p_adjusted (numeric, NA where p_value is) and
significant (logical) columns; the class and attributes of
x are kept, and a scan_adjust attribute lists
method, alpha and tests.
Details
For a rate_change() table, conditional on the two counts' total
the current count is binomial with success probability
\(t_a / (t_a + t_b)\), the share of the combined exposure in the
current period, and the p-value is the two-sided exact binomial test of
that. Rows without a p-value (no comparison period, both counts zero)
are left out of the adjustment, so the number of tests is the number of
rows with a p-value; it is recorded in the scan_adjust attribute.
The adjustment is stats::p.adjust(p, method): "BH" controls
the expected proportion of false discoveries among the rows declared
significant, which suits a screen; "holm" and "bonferroni"
control the chance of any false discovery, which a claim about one
specific row needs. A row is significant when its adjusted p-value
is strictly below alpha.
Errors: x not a data frame; no p_value column and not a
yoy() or rate_change() result; a yoy() result
without count units; a p-value outside \([0, 1]\); a method unknown to
p.adjust().
See also
yoy_pvalues, falsify_family for a
family of falsification results, drift_calibrate.
Examples
seg <- data.frame(year = rep(2022:2023, each = 3),
site = rep(c("A", "B", "C"), 2),
n = c(30, 50, 80, 45, 52, 79))
y <- yoy(seg, value = "n", period = "year", by = "site")
scan_adjust(y)[, c("site", "pct_change", "p_value", "p_adjusted")]
#> <rmbl_yoy: no periods>
# family-wise control instead of the false discovery rate
scan_adjust(y, method = "holm")$p_adjusted
#> [1] NA 0.3160268 NA 1.0000000 NA 1.0000000
# any table with a p_value column
scan_adjust(data.frame(test = c("a", "b", "c"), p_value = c(0.001, 0.02, 0.4)))
#> test p_value p_adjusted significant
#> 1 a 0.001 0.003 TRUE
#> 2 b 0.020 0.030 TRUE
#> 3 c 0.400 0.400 FALSE
try(scan_adjust(data.frame(p_value = 1.5)))
#> Error : `p_value` must lie in [0, 1]; row(s) 1 hold 1.5. Nothing outside that range is a probability, so no adjustment or significance decision is made.
