#' @importFrom mgcv fix.family.rd
`fix_family_rd` <- function(family, ncores = 1, ...) {
# try to fix up the family used by mgcv to add the $rd component
# for random deviate sampling
# try the obvious thing first and see if mgcv::fix.family.rd() already handles
# family
fam <- mgcv::fix.family.rd(family)
# if `family` contains a NULL rd we move on, if it is non-null return early
# as it doesn't need fixing
if (!is.null(fam$rd)) {
return(fam)
}
# handle special cases
fn <- family_name(fam)
# handle multivariate normal
if (identical(fn, "Multivariate normal")) {
# note: mgcv::mvn is documented to ignore prior weights
# if we ever need to handle weights to scale V, see this post on CV
# https://stats.stackexchange.com/a/162885/1390
rd_mvn <- function(V) {
function(mu, wt, scale) { # function needs to take wt and scale
mgcv::rmvn(
n = nrow(mu),
mu = mu,
V = V
)
}
}
fam$rd <- rd_mvn(solve(crossprod(fam$data$R)))
}
if (identical(fn, "twlss")) {
# this uses some helpers to find the `a` and `b` used during fitting and
# also to convert what `predict()` etc returns (theta) to power parameter
rd_twlss <- function(a, b) {
function(mu, wt, scale) {
rtw(
mu = mu[, 1], # fitted(model) for twlss is on response scale!
p = theta_2_power(theta = mu[, 2], a, b),
phi = exp(mu[, 3])
)
}
}
tw_pars <- get_tw_ab(fam)
fam$rd <- rd_twlss(a = tw_pars[1], b = tw_pars[2])
}
# return modified family
fam
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.