--- title: "Poisson rate outcomes" author: "metaGLMM authors" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Poisson rate outcomes} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r setup, include=FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", fig.width = 6, fig.height = 4) set.seed(20260821) library(metaGLMM) ``` ## Rates from aggregate counts For a Poisson analysis, use a rate as the response and the corresponding exposure as `ni`. A small positive variance approximation is useful for the aggregate-data representation, especially when an observed count is zero. ```{r data} poisson_dat <- data.frame( study = paste0("Study ", 1:12), sex = factor(rep(c("Female", "Male"), 6)), year = c(0, 0, 2, 2, 6, 6, 6, 6, 7, 7, 8, 8), events = c(13, 1, 16, 3, 38, 3, 13, 4, 5, 10, 11, 23), exposure = c(9.04, 8.46, 23.75, 23.75, 18.47, 18.47, 9.38, 9.19, 2.27, 3.34, 2.72, 26.00) ) poisson_dat$rate <- poisson_dat$events / poisson_dat$exposure poisson_dat$vi <- 1 / pmax(0.5, poisson_dat$events) poisson_dat ``` ## Basic single-group meta-analysis and forest plot An intercept-only model estimates the overall log rate while allowing each study to have its own random effect. This is the direct single-group analogue of a conventional random-effects meta-analysis. ```{r basic-fit} poisson_mean_fit <- metaGLMM( rate ~ 1, data = poisson_dat, vi = poisson_dat$vi, ni = poisson_dat$exposure, tau2 = NA, family = poisson(link = "log"), tau2_var = TRUE, fast = TRUE, ghq_Q = 40L ) summary(poisson_mean_fit) coef(poisson_mean_fit) confint(poisson_mean_fit, method = "wald") stopifnot(is.finite(poisson_mean_fit$tau), poisson_mean_fit$tau > 0) ``` Each forest row is one observed study rate. `type = "exp"` converts the study estimates, pooled intervals, and prediction interval from the log-rate scale to the rate scale. ```{r basic-forest} poisson_studies <- as_metafor_data( poisson_mean_fit, labels = poisson_dat$study ) head(poisson_studies) forest( poisson_mean_fit, labels = poisson_dat$study, type = "exp", xlab = "Rate", ci_methods = c("Wald", "profile", "SBC") ) ``` ## Meta-regression with moderators The formula can include factors, continuous moderators, and interactions. The coefficient names are the names generated by `model.matrix()`. ```{r fit} poisson_fit <- metaGLMM( rate ~ sex + year + sex:year, data = poisson_dat, vi = poisson_dat$vi, ni = poisson_dat$exposure, tau2 = NA, family = poisson(link = "log"), tau2_var = TRUE, fast = TRUE, ghq_Q = 40L ) summary(poisson_fit) coef(poisson_fit) exp(coef(poisson_fit)) ``` The exponentiated coefficients are rate ratios relative to the factor reference level and at `year = 0`. Center `year` before fitting when another reference year is more meaningful. Because this model has several fixed effects, a pooled forest summary would require an explicitly chosen coefficient or contrast; the basic intercept-only fit above is the clearer study-rate display. ## Offsets An offset is part of the ordinary formula interface. For example, when the response is defined on a count scale, the model matrix contains the exposure offset as follows: ```{r offset, eval=FALSE} count_formula <- events ~ sex + year + offset(log(exposure)) model.matrix(count_formula, data = poisson_dat) ``` Choose either a rate response with exposure supplied through `ni` or a count response with a formula offset according to the sampling convention of the analysis; keep the response and the exposure definition consistent.