R’s hypothesis testing functions are inconsistent. t.test() returns a different structure than chisq.test(). Writing generic code that works across tests is painful. hypothesize fixes this with a unified API where every test returns the same interface.
The Problem
Different R tests return incompatible objects:
t.test(x, y)$p.value # Works
chisq.test(x, y)$p.value # Also works
my_custom_test(x, y)$??? # Who knows?
You cannot write generic code that works across tests without knowing the internals of each one.
The Fix
hypothesize defines a consistent interface:
test <- lrt(model_null, model_alt) # Likelihood ratio test
pval(test) # Extract p-value
test_stat(test) # Extract test statistic
dof(test) # Extract degrees of freedom
is_significant_at(test, 0.05) # Boolean check
All tests, built-in or custom, implement the same generic functions. The interface is the same whether you are doing a likelihood ratio test, a Wald test, or a Z-test.
Integration with likelihood.model
The package works with likelihood.model, so likelihood ratio tests on any model are straightforward:
lrt(null_model, alternative_model) # Automatic LRT
You specify the models. The package computes the test statistic, degrees of freedom, and p-value. Same interface as every other test.
The Point
Tests are objects you manipulate, not functions with incompatible return types. You can write test-agnostic pipelines. You can wrap your own custom tests in the same interface. This is generic programming applied to hypothesis testing: a consistent abstraction over heterogeneous implementations.
R package – Works with likelihood.model – Documentation – GitHub
Discussion