Combines hypothesis tests using the OR rule: rejects when ANY component test rejects.

union_test(...)

Arguments

...

hypothesis_test objects or numeric p-values to combine.

Value

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.

Details

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)\).

Multiplicity Warning

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.

Boolean Algebra

Together with intersection_test() (AND) and complement_test() (NOT), this forms a complete Boolean algebra over hypothesis tests:

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)))

See also

intersection_test() for AND, complement_test() for NOT, fisher_combine() for evidence pooling

Examples

# 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