When using GAMs to model ecological count data (e.g., fish counts) using Poisson or negative-binomial distributions, the response variable is raw counts and the offset (e.g., log-transformed fishing effort) is included using the offset() or offset= functions. However, when making predictions based on model fits, the predict.gam() function doesn't explicitly incorporate the offset variable.

Questions, in no particular order:

  1. Why is the offset typically log-transformed? Is it a rule?
  2. Can the offset be included as a main effect instead of using the "offset()" or "offset=" functions in order to include it in model predictions?
  3. Is it acceptable to pre-calculate a standardized response variable (e.g., fish catch-per-unit-effort), multiply the number to avoid fractions (which aren't suitable for Poisson and negative-binomial models), and then avoid using the offset altogether?

In my research group, we're getting a lot of questions such as these from our professors/ committee members/ reviewers, so any insight to help us clarify/ justify our approaches would be much appreciated.


2 Answers 2


For your first question, see Goodness of fit and which model to choose linear regression or Poisson.

For the second one, I think the answer is NO.

The third one seems to be answered at Predicting with GAM, using an offset



The offset term has to be specified (in R at least) on the scale of the linear predictor. Because the canonical (and default) link function in Poisson and negative binomial models is the log link, any example that fits this default model with an offset that you will have encountered will have a linear predictor that is on the log scale and hence will have to log transform the offset variable to this same scale.

But other link functions are allowed; R's poisson() allows for "log", "identity", and "sqrt". If you used a link function other than "log" from the list of allowed ones for the Poisson, then you would need to enter your offset on that scale, not the log scale. Whether such a model would make sense or have the same interpretation is a different question; the log in the offset/link has the property that we end up modelling the expected value of $y_i / N_i$:

$$ \begin{align} y_i &\sim \text{Poisson}(\mu_i) \\ g(\mu_i) &= \beta_0 + \beta_1 x_{1i} + \log (N_i) \\ \mu_i &= g(\beta_0 + \beta_1 x_{1i} + \log(N_i))^{-1} \\ &= \exp(\beta_0 + \beta_1 x_{1i} + \log(N_i)) \\ &= N_i \exp(\beta_0 + \beta_1 x_{1i}) \\ \mu_i / N_i &= \exp(\beta_0 + \beta_1 x_{1i}) \end{align} $$

The last line shows that the GLM defined in lines 1 and 2 is equivalent to modelling the expectation of the scaled mean count $\mu_i$, where the scaling is by division by the offset term (fishing effort).


I'm not sure either; if you add the offset as a fixed effect, you will have a term $\beta_j N_i$ or $\beta_j \log(N_i)$ in place of $\log(N_i)$ in the above equations. So the match doesn't work out so cleanly; you won't be dividing by $N_i$ at best it will be by $\beta_j N_i$, but I haven't sat down and worked this math out myself.


This is going to get you into more trouble. If you don't try to turn everything into integers you could use a family that allow for non-negative continuous responses. Unfortunately, there aren't many of those kinds of distributions available in the modelling functions in R. The Tweedie family of distributions is one such distribution, but that's not natively available for glm(), glmer() etc though there is the statsmod 📦 and also the mgcv 📦 and glmmTMB 📦. The Gamma and inverse.gaussian families would also be an option but as they don't allow for 0 values, you'll run into trouble with your suggestion if any of the counts take this perfectly valid value.

If you do multiply to make everything a nice integer, you're inevitably going to need to use a large number to get rid of all the decimal places or you'll need to round the data. Multiplying by a very large number is likely to run you into computational difficulties, especially if you try more complex types of model (GLMMs say). Rounding will result in the data being interval censored: say you round the value 20.54, you get a value that is 21, but it could have been any value in the interval [20.5, 21.5), as any other value 20.5 <= x < 21.5 will be rounded to 21. And that way lies another world of pain.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.