Combines hypothesis tests using the OR rule: rejects when ANY component test rejects.
union_test(...)A hypothesis_test object of subclass union_test. The stat
and dof fields are NA (no natural test statistic for p-value
aggregation). Metadata fields: n_tests and component_pvals.
The union test implements the OR operation in the Boolean algebra of hypothesis tests. It is defined via De Morgan's law:
$$\text{union}(t_1, \ldots, t_k) = \text{NOT}(\text{AND}(\text{NOT}(t_1), \ldots, \text{NOT}(t_k)))$$
This is not an approximation — it is the definition. The implementation
is literally the De Morgan law applied to complement_test() and
intersection_test().
The resulting p-value is \(\min(p_1, \ldots, p_k)\).
The uncorrected \(\min(p)\) is anti-conservative when testing multiple
hypotheses. If you need to control the family-wise error rate, apply
adjust_pval() to the component tests before combining, or use
fisher_combine() which pools evidence differently.
The raw union test is appropriate when you genuinely want to reject a global null if any sub-hypothesis is false, without multiplicity correction — for example, in screening or exploratory analysis.
Together with intersection_test() (AND) and complement_test() (NOT),
this forms a complete Boolean algebra over hypothesis tests:
AND: intersection_test() — reject when all reject
OR: union_test() — reject when any rejects
NOT: complement_test() — reject when original fails to reject
De Morgan's laws hold by construction:
union(a, b) = NOT(AND(NOT(a), NOT(b)))
intersection(a, b) = NOT(OR(NOT(a), NOT(b)))
intersection_test() for AND, complement_test() for NOT,
fisher_combine() for evidence pooling
# Screen three biomarkers: reject if ANY is significant
t1 <- wald_test(estimate = 0.5, se = 0.3)
t2 <- wald_test(estimate = 2.1, se = 0.8)
t3 <- wald_test(estimate = 1.0, se = 0.4)
union_test(t1, t2, t3)
#> Hypothesis test (union_test)
#> -----------------------------
#> Test statistic: NA
#> P-value: 0.00866489672602513
#> Degrees of freedom: NA
#> Significant at 5% level: TRUE
# De Morgan's law in action
a <- wald_test(estimate = 2.0, se = 1.0)
b <- wald_test(estimate = 1.5, se = 0.8)
# These are equivalent:
pval(union_test(a, b))
#> [1] 0.04550026
pval(complement_test(intersection_test(complement_test(a), complement_test(b))))
#> [1] 0.04550026