The following is a question posted to Stack Overflow, but the answer is more to-do with statistical theory than software. I am reposting it here because this is a more appropriate venue, and because similar questions have remained unanswered on this site for 8+ years.
Poisson regression can be fit to raw data or can be fit by summarizing data and then using an offset. The model should return the same coefficient estimates (as well as covariance estimates), regardless of the approach (full data or offset).
However it seems the sandwich
function from {sandwich}
returns different covariance estimates when the model uses an offset. This is particularly troubling because this means the confidence intervals and p values are effected.
Shown below is such an example. The two covariance matrices differ when they are expected to be the same.
Is this intended behaviour?
library("tidyverse")
grouped_data <- tibble::tribble(
~treatment, ~g, ~y, ~N,
"A", "a", 1338L, 20669L,
"A", "b", 36L, 1237L,
"A", "c", 2555L, 39438L,
"A", "d", 402L, 5713L,
"B", "a", 1281L, 19986L,
"B", "b", 38L, 1224L,
"B", "c", 2495L, 36749L,
"B", "d", 382L, 5646L
)
Re-organize data to be as if we hadn't grouped and summarized
by uncounting the number of successes (y
)
and number of failures (N
- y
)
yes_outcomes <-grouped_data %>%
mutate(yy=1) %>%
uncount(y)
no_outcomes <-grouped_data %>%
mutate(yy=0) %>%
uncount(N-y)
# This is equivalent to the data we had before grouping
unit_data <- bind_rows(yes_outcomes, no_outcomes) %>%
select(-y) %>%
rename(y=yy)
Fit one model on the ungrouped data without offset and one model on the grouped data with offset.
fit <- glm(y ~ treatment + g, data = unit_data, family = poisson)
offset_fit <- glm(y ~ treatment + g, data = grouped_data, family = poisson,
offset = log(N))
The corresponding sandwich
results are:
sandwich::sandwich(fit)
#> (Intercept) treatmentB gb gc
#> (Intercept) 0.0004689434 -2.213726e-04 -3.599604e-04 -3.621573e-04
#> treatmentB -0.0002213726 4.385850e-04 5.526098e-06 9.843754e-06
#> gb -0.0003599604 5.526098e-06 1.346409e-02 3.572512e-04
#> gc -0.0003621573 9.843754e-06 3.572512e-04 5.422671e-04
#> gd -0.0003545652 -5.331337e-06 3.572202e-04 3.571526e-04
#> gd
#> (Intercept) -3.545652e-04
#> treatmentB -5.331337e-06
#> gb 3.572202e-04
#> gc 3.571526e-04
#> gd 1.544801e-03
sandwich::sandwich(offset_fit)
#> (Intercept) treatmentB gb gc
#> (Intercept) 1.672258e-04 -8.616787e-05 -1.238920e-04 -1.263405e-04
#> treatmentB -8.616787e-05 1.742927e-04 -1.483730e-06 3.456605e-06
#> gb -1.238920e-04 -1.483730e-06 3.554277e-04 1.246024e-04
#> gc -1.263405e-04 3.456605e-06 1.246024e-04 2.040329e-04
#> gd -1.237209e-04 -1.827624e-06 1.246399e-04 1.245998e-04
#> gd
#> (Intercept) -1.237209e-04
#> treatmentB -1.827624e-06
#> gb 1.246399e-04
#> gc 1.245998e-04
#> gd 5.878420e-04
Created on 2023-02-19 by the reprex package (v2.0.1)