Diagnostics for HierArchical Regression Models
I receive a lot of requests for supporting further R packages with DHARMa, so here are a few general technical comments regarding this topic:
First of all, if you have an unsupported model, there are two options to create DHARMa residual plots:
If feasible, option 1 is obviously preferable, so I’ll start with this, followed by the fallback option 2.
DHARMa interacts with other regression packages through a number of S3 wrapper functions which are available and described in the file compatibility.R.
For each wrapper, there is a default function. These default functions essentially assume that the following functions / options are implemented and work as for glm / lme4.
If your model class implements these points identically to lm/glm/lme4, chances are good that DHARMa will work out of the box, even if a warning is produced.
If that is not the case, you (or I) have to create a new S3 wrapper (e.g., getSimulations.YourClass) to extract simulations from the fitted model using your model syntax. Of course, this assumes that the respective functions / options are implemented by your model class in the first place. Regarding the latter, my strong preference is that:
The sense of this separation of work is that functions related to a specific package should stay and be maintained with this package, not with DHARMa.
Usually I write the wrapper function myself, it’s enough that you provide the S3 functions needed for DHARMa with your model, but of course you can also create a (tested) pull request with all the necessary wrapper functions, after discussing it in an issue (see CONTRIBUTING.md), which would allow me to integrate your package seamlessly into DHARMa.
If your model is not supported by DHARMa, you can still simulate data by hand and read this into DHARMa, allowing you to perform most of the residual checks implemented. This is easiest if your model already has a simulate function implemented, which allows creating new data based on the assumptions and parameters of a fitted statistical model, as in:
fit <- glm(...)
newData <- simulate(fit)
A simulate function is a very useful extension of any advanced regression package, as it allows performing a number of essential tasks for technical validation, statistical validation, and non-parametric methods, such as
If a simulate function is not available, the best option would be to ask the maintainers of the respective regression package to create a simulate function, or create one yourself and make a pull request.
Note for developers:
If a simulate function is not available, you could still take out the parameters of the fitted model, and simulate new data according to these parameters. Here is an example for a Poisson GLM:
testData = createData(sampleSize = 50, randomEffectVariance = 0)
fittedModel <- glm(observedResponse ~ Environment1, data = testData, family = "poisson")
# in DHARMa, using the simulate.glm function of glm
sims = simulateResiduals(fittedModel)
plot(sims, quantreg = FALSE)
# Doing the same with a hand-coded simulate function.
# of course this code will only work with a 1-par glm model
simulateMyfit <- function(n=10, fittedModel){
int = coef(fittedModel)[1]
slo = coef(fittedModel)[2]
pred = exp(int + slo * testData$Environment1)
predSim = replicate(n, rpois(length(pred), pred))
return(predSim)
}
sims = simulateMyfit(250, fittedModel)
dharmaRes <- createDHARMa(simulatedResponse = sims, observedResponse = testData$observedResponse, fittedPredictedResponse = predict(fittedModel, type = "response"), integer = T)
plot(dharmaRes)
Another example is given in a blog post on using DHARMa for residual checks of unsupported models.
Once you have an option to simulate, you can always read in the simulations via createDHARMa, which allows using most options of the DHARMa package.