R Programming / Evaluation, ownership, and reproducible results / Lesson 13
Formulas, contrasts, and generalized models
Inspect coding and response scale before interpreting a model coefficient or prediction.
On this page
Lesson goals
- Expand formula terms and identify contrast columns.
- Distinguish a GLM family from its link function.
- Validate grouped-binomial counts and prediction scale.
Formula syntax is a modeling language
In a formula, a*b includes a, b, and their interaction a:b; it does not simply compute an elementwise product. I(a*b) requests ordinary arithmetic inside a term. Removing an intercept changes the coding and interpretation of other columns. Transforming a response, specifying a link, and adding an offset are also different operations. Build and inspect a tiny model matrix before interpreting a complex specification. Its columns connect the symbolic formula to the actual numeric predictor, and reveal whether the intended main effects, interactions, and reference levels entered the calculation.
Contrasts define comparisons between categories
The first fixture declares a two-level factor and an explicit treatment contrast. The control row contains intercept one and indicator zero; the treated row contains two ones. Under this coding, a linear-model intercept refers to the control conditional mean and the indicator coefficient represents a difference on the modelโs linear predictor scale. Other contrast choices can represent different comparisons without changing the fitted function space in a full-rank equivalent model. Changing coding changes coefficient meaning, so preserve the contrast contract when sharing a fit or constructing new-data matrices.
d <- data.frame(group = factor(c("control", "treated", "control"),
levels = c("control", "treated")))
X <- model.matrix(~ group, data = d,
contrasts.arg = list(group = contr.treatment(c("control", "treated"), base = 1)))
cat("columns=", ncol(X), "\n", sep = "")
cat("control row=", paste(X[1, ], collapse = ","), "\n", sep = "")
cat("treated row=", paste(X[2, ], collapse = ","), "\n", sep = "")
columns=2
control row=1,0
treated row=1,1
An explicit treatment contrast gives an intercept and a treated indicator; the reference category is declared rather than inherited from global options.
A generalized model separates family and link
A generalized linear model combines a linear predictor with a response distribution family and a link relating the conditional mean to that predictor. A binomial-logit model expresses log odds linearly; predict with type="response" returns probabilities while the link scale remains log odds. A Poisson model commonly uses a log link for nonnegative counts, but exposure, overdispersion, and dependence need separate attention. A convenient family name does not validate those assumptions. State the observational unit, mean target, variance structure, and exposure interpretation before choosing a model from its output range alone.
Grouped responses preserve their denominators
The second fixture supplies success and failure counts as a two-column response. Its intercept-only estimate pools three successes out of eight trials, producing probability 0.375 and log odds log(3/5). Treating the two proportions as equally weighted observations would ignore their denominators when trial totals differ. Validate nonnegative counts, total trials, response ordering, and missingness explicitly. Separation or sparse categories can make some logistic fits difficult or nonidentifiable; convergence flags and extreme coefficients require investigation. This synthetic intercept fit is a small interface example, not evidence that a complex real model is well specified.
d <- data.frame(success = c(2, 1), failure = c(2, 3))
fit <- glm(cbind(success, failure) ~ 1, data = d,
family = binomial(link = "logit"), na.action = na.fail)
cat(sprintf("logit=%.6f\n", unname(coef(fit)[1])))
p <- predict(fit, type = "response")
cat("probabilities=", paste(sprintf("%.3f", p), collapse = ","), "\n", sep = "")
logit=-0.510826
probabilities=0.375,0.375
The intercept-only grouped-binomial fit pools three successes in eight trials; response predictions differ from the linear predictor scale.
Predictions retain the entire modeling contract
Keep factor levels, contrasts, offsets, transformations, and units alongside the fitted object. An offset is a known contribution with coefficient fixed by design, not an ordinary predictor whose effect is estimated. When using transformations learned from data, preserve their training-only parameters rather than recomputing them from new observations. Inspect warnings, convergence status, rank, and relevant residual behavior before interpreting a coefficient. Report uncertainty and limitations according to the design. The expected results here are analytically derived; no formula parser, contrast builder, GLM optimizer, or prediction routine was executed in R during review.
Common errors and fixes
A coefficient is read as a probability difference in logistic regression
- Why it happens
- The coefficient is on the log-odds linear predictor scale.
- How to fix it
- Transform predictions under the declared link and state the comparison.
- Prevent it next time
- Label every displayed prediction with its scale.
A model changes after a factor reference is reordered
- Why it happens
- The contrast columns changed their meaning.
- How to fix it
- Preserve or explicitly redefine levels and contrasts.
- Prevent it next time
- Inspect a tiny model matrix before comparing coefficients.
Proportions with different trial totals receive equal weight accidentally
- Why it happens
- The grouped-binomial denominator was discarded.
- How to fix it
- Supply success/failure counts or an equivalent documented weighted representation.
- Prevent it next time
- Validate both outcome counts and total trials.
Check your understanding
1. Expand y ~ a*b and explain how it differs from y ~ I(a*b).
Show worked solution
The first formula includes a, b, and their interaction a:b, plus the ordinary default intercept. The second includes the computed arithmetic product as one term with an intercept. For numeric variables the resulting columns generally differ; inspect model.matrix rather than relying on the visual similarity of the expressions.
2. Two groups have one success in two trials and nine successes in ten trials. What is the pooled intercept-only probability?
Show worked solution
The pooled estimate is ten successes divided by twelve trials, or 5/6. The equal-weight mean of the two proportions is (0.5+0.9)/2=0.7 and answers a different weighting question. Keep denominators visible when defining the response.
Key takeaways
- Formula operators and arithmetic operators have different roles.
- Coding and link scale determine coefficient interpretation.
- Grouped outcomes require their trial counts.