Skip to content
Prev 31368 / 63424 Next

proposed simulate.glm method

Yes, thanks to Ben for getting the ball rolling. His code was more
streamlined than mine, pointing to further simplifications which I've
included in the extended version below.

The code for the additional families uses functions from MASS and
SuppDists - I wasn't sure about the best way to do this, so have just
used :: for now.

It appears to be working happily for both glm and gnm objects (no
gnm-specific code used).

Best wishes,

Heather

simulate.glm <- function (object, nsim = 1, seed = NULL, ...)
{
    fam <- object$family$family
    if(fam == "gaussian")
	return(simulate.lm(object, nsim=nsim, seed=seed, ...))
    if(!exists(".Random.seed", envir = .GlobalEnv, inherits = FALSE))
	runif(1)		       # initialize the RNG if necessary
    if(is.null(seed))
	RNGstate <- get(".Random.seed", envir = .GlobalEnv)
    else {
	R.seed <- get(".Random.seed", envir = .GlobalEnv)
	set.seed(seed)
	RNGstate <- structure(seed, kind = as.list(RNGkind()))
	on.exit(assign(".Random.seed", R.seed, envir = .GlobalEnv))
    }
    ## get probabilities/intensities
    pred <- object$fitted
    ntot <- length(pred) * nsim
    val <- switch(fam,
		  "poisson" = rpois(ntot, pred),
		  "binomial" = {
                      wts <- object$prior.weights
                      if (any(wts %% 1 != 0))
                          stop("cannot simulate from non-integer
prior.weights")
		      rbinom(ntot, size = wts, prob = pred)/wts
		  },
                  "Gamma" = {
                      shape <- MASS::gamma.shape(object)$alpha
                      rgamma(ntot, shape = shape, rate = shape/pred)
                  },
                  "inverse.gaussian" = {
                      lambda <- 1/summary(object)$dispersion
                      SuppDists::rinvGauss(ntot, nu = pred, lambda = lambda)
                  },
		  stop("family '", fam, "' not yet implemented"))
    ans <- as.data.frame(matrix(val, ncol = nsim))
    attr(ans, "seed") <- RNGstate
    ans
}
Martin Maechler wrote: