Skip to content

Cache results of a heteroscedasticity test

Source: R/performance.R ยท Help: ?cachedTest

Runs a registered diagnostic, and returns the result of an earlier call on the same inputs instead when the diagnostic is deterministic.

Usage

cachedTest(test_name, model, data, ..., use_cache = TRUE)

Arguments

test_name
Character scalar naming a diagnostic of the registry (listDiagnostics()) or of test_factory.
model
Fitted model object supplied to the diagnostic.
data
Data frame used to fit the model.
...
Additional arguments forwarded to the diagnostic.
use_cache
Logical scalar: may the result be read from the cache and stored in it? FALSE runs the diagnostic. Defaults to TRUE.

Value

The diagnostic result, either retrieved from cache or freshly computed. A result whose data.name is "model", the name of the argument of the function the registry calls the test with, reports the formula of the model instead, as in runHeteroTests(), since 0.18.0; White's test, its bootstrap, the studentized Breusch-Pagan statistic and Szroeter's test reported "model" here before. The cache keeps the result as the test returns it, and the rule applies to a result read from it too. Unlike a result of runHeteroTests(), it has no attr(, "extras")$streaming, which says how the runner ran a test.

Details

What is cached. Only the deterministic tests the package registers: "white", "breusch_pagan", "koenker", "cook_weisberg", "ncv", "spread_level", "student_bp", "szroeter", "quantile_regression", "high_dimensional" and "variance_form".

What is not. A test that draws random numbers is never cached: "wild_bootstrap", "white_bootstrap", "rank_permutation" and "spatial_hetero" run on every call, so a seeded call returns what it returns without the cache, and leaves the random number generator where it leaves it without the cache. Nor is "box_m", which tests data rather than a model, a diagnostic added with registerDiagnostic() or test_factory$register(), or one registered again under a name of the package: the package cannot know whether it draws random numbers or reads anything besides its inputs. A result whose computation moved the random number generator is not stored either. Before 0.16.0 every name was cached, the resampling tests included: a call with another seed returned the replicates of the first, and the random numbers drawn after it were not those of a call without the cache.

The key. The test, its arguments, and the parts of the model and of the data the test reads: the class of the model, its family and link; from the model context of the fit, its model frame, response, design, residuals and fitted values, prior weights, total offset, rank and aliased coefficients, the names of its observations and its na.action; its coefficients, the weights it stores, its terms (with their predvars), call, contrasts and levels, residual degrees of freedom, whether it keeps its model frame, and its attributes, such as the variance function of a fitWLS() fit; and data, whole: its values, row names, class and attributes. The key is an xxhash64 digest of those values (from the digest package; without it nothing is cached). It holds values, not environments: a model refitted to the same data, in another environment or another session, has the same key and is answered from the cache, with the model of the call as attr(result, "model"), so that the result is identical() to the one the test computes. A model the tests refuse before reading it, such as a fit with model = FALSE whose data changed after the fit, has no key and is refused as without the cache; so has a fit with model = FALSE whose data are gone, whose model frame the tests rebuild from data, and it runs without the cache.

What the key leaves out. The key does not hold the environment of the formula: a test that evaluates the formula on data again, as the check of the rows of data does, reads the functions and variables of that environment as they are, so that after f is defined again a model y ~ f(x) is answered with the result computed with the old f, where without the cache the check may refuse data. Clear both caches, with clearTestCache() and clearAnalysisCache(), after changing one of them. Nor does it hold the options of the session: a result read from the cache gives none of the warnings and messages of the call that computed it but one (below), so a call made under options(warn = 2) after one that stored its result is answered with that result, where without the cache a warning of the test, turned into an error, stops it. The results of the tests otherwise do not depend on the options; the names of the estimates of the quantile regression test depended on options(digits) before 0.16.0.

Before 0.16.0 the key held only the test, the coefficients, the residuals, data and the arguments. Fits that share those shared one entry, and the second call returned the result of the first: lm(y ~ x + offset(o)) and lm(I(y - o) ~ x), which have the same coefficients and residuals and other fitted values; a fit and the same fit with its weights changed, which the tests refuse; or a fit with model = FALSE before and after its data changed, which they refuse too.

The bound. The cache holds at most getOption("heteroTests.cache_size", 100) results, and drops the one used least recently to store another; options(heteroTests.cache_size = 0) turns it off, together with the cache of runHeteroTests(). A stored result keeps no copy of the model. Before 0.16.0 the cache grew without bound, by about 25 KB per call on a new model, and kept about 0.3 KB per call after clearTestCache(). The checks the tests make first keep their results in a cache of their own, of at most getOption("heteroTests.validation_cache_size", 1000) results, which 0 turns off; it holds no check that drew random numbers.

A result read from the cache is returned without running the test, so the call gives none of the warnings and messages of the call that computed it, but one: since 0.16.0 the warning White's, Koenker's and the Breusch-Pagan tests give on a factor with more levels than observations per level, of class heteroTests_fixed_effects_warning, is stored with the result and given again on every call that reads it, as by runHeteroTests() (see Fixed effects for small groups in performKoenkerTest()). The call that computes the result gives it once the result is stored, so that under options(warn = 2) the warning stops the call after the result is stored.

See also

clearTestCache() empties the cache; runHeteroTests() uses it with use_cache = TRUE.