- Ignoring the implicit intercept, which set of terms remains after R expands the formula?
Answer: The three main effects plus a:c and b:c, but neither a:b nor a:b:c.
When reading R model formulas, you need to understand two rules: the ^n operator expands all interactions up to order n, and subtracting a term (e.g., -a:b) explicitly removes it from the expanded result — it does not trigger any promotion or cascading effects.
Starting with (a + b + c)^2, R expands this into all main effects plus all pairwise interactions: a, b, c, a:b, a:c, and b:c. Notice that ^2 caps expansion at two-way interactions, so a:b:c is never generated in the first place. Then -a:b simply removes a:b from that list, leaving you with the three main effects plus a:c and b:c. That's exactly what answer A describes, making it correct.
Answer B is wrong because ^2 limits expansion to interactions of order two or less — the three-way interaction a:b:c is never included, regardless of whether you subtract anything afterward. Answer C reflects a misunderstanding of how parentheses work in R formulas; (a + b + c)^2 does not strip main effects. The ^ operator means "expand to this interaction depth," and main effects are always retained unless you explicitly remove them with something like -a. Answer D introduces the fictional idea that subtracting a lower-order term "promotes" a higher-order term — R has no such behavior. Subtraction is purely a removal operation.
A handy rule to remember: in R formulas, ^n adds terms up to order n, and -term removes exactly that term. Neither operation causes cascading changes to other terms in the model.
- How does R expand the right side of this formula?
Answer: site + site:block, representing blocks nested within sites.
When you see the / operator in an R formula, think "nesting." The slash is shorthand for a specific hierarchical relationship: the term on the right is nested within the term on the left, meaning the right-side grouping only makes sense in the context of the left-side grouping. This is exactly the scenario described — block labels repeat across sites, so blocks have no global meaning on their own.
R expands site / block as site + site:block. The site term captures the main effect of each site, and site:block captures the interaction of site with block — which effectively defines unique blocks within each site. This makes B the correct answer. The expansion correctly accounts for the fact that "block 1 at site A" and "block 1 at site B" are completely different experimental units.
A is wrong because site + block treats block as a global, crossed main effect — as if block labels were consistent and meaningful across all sites. That's the opposite of a nested structure. C is wrong for a similar reason: retaining a standalone block term implies blocks exist independently of sites, which contradicts the nested design and also drops the site main effect entirely. D is wrong because site * block expands to site + block + site:block, which again includes a global block main effect that's meaningless when block labels are reused across sites.
A useful memory trick: read / as "within" — a / b means "b within a," which R translates to a + a:b. Whenever block or group labels are reused across higher-level units, nesting with / is almost certainly what you need.
- Which statement correctly describes the role of
exposure in this model? Answer: Its logged value enters the linear predictor with its coefficient fixed at 1, adjusting for differing observation periods.
Whenever you see offset(...) in a glm() call, the key question to ask is: how does this term enter the linear predictor, and is its coefficient estimated or fixed?
In a Poisson model with log link, the linear predictor takes the form log(μ)=β0+β1⋅temperature+log(exposure). The offset() wrapper forces the coefficient on log(exposure) to equal exactly 1 — it is not estimated from the data. This means the model is effectively modeling the rate μ/exposure, while still treating raw counts as the response. This is answer A, which correctly states that the logged exposure enters the linear predictor with its coefficient fixed at 1, adjusting for unequal observation windows or population sizes.
B is wrong because it describes an ordinary covariate — if you simply wrote + log(exposure) without offset(), R would estimate a free coefficient for it, which is a meaningfully different model.
C is wrong because the response remains the raw count; the model does not internally replace it. The rate interpretation is a consequence of the offset algebra, not a literal transformation of the response variable.
D is wrong because offset() only affects exposure — it computes log(exposure) and fixes its coefficient. temperature is left completely untouched and enters the model on its original scale.
A useful rule of thumb: offset() = "include this log-transformed variable but don't estimate its slope — assume it equals 1." Any time you see it, think rate adjustment, not free parameter estimation. - Which formula specifies that structure most directly?
Answer: y ~ treatment * site, which includes both main effects and their interaction.
When building regression formulas in R, your goal is to match the model structure to the research question. Here, the analyst wants treatment differences to vary by site — that's the definition of an interaction — while still keeping both main effects in the model. That combination points directly to the * operator.
In R, y ~ treatment * site expands to y ~ treatment + site + treatment:site, giving you the main effect of treatment, the main effect of site, and their interaction term. This lets the effect of treatment differ across sites while still estimating each factor's overall contribution — exactly what the passage describes.
Choice A (y ~ treatment + site) is the additive model. It assumes treatment differences are constant across every site, which contradicts the requirement that those differences be allowed to vary. Choice B (y ~ treatment:site) includes only the interaction term and drops both main effects entirely — statistically unusual and rarely what you want, since you lose the interpretable baseline effects of each factor. Choice D (y ~ treatment / site) uses nesting notation, which expands to treatment + treatment:site; it models site within treatment levels and omits site's independent main effect, which misrepresents the structure described.
Choice C is correct because * is R's shorthand for "main effects plus their interaction," matching the analyst's goal precisely.
A handy rule: memorize the three interaction operators — + (additive only), : (interaction only), and * (both main effects and interaction). On exam questions involving factorial designs, ask yourself whether the research question demands varying effects across groups; if yes, you almost certainly need *.
- Which variables are used as predictors by this model?
Answer: Only x and w; y, z, and the external object q are not predictors.
When you see a formula like y ~ . - z in R's lm(), you need to understand exactly what the dot (.) means and where it looks for variables. The dot is shorthand for "all variables in the data argument," not all objects in your R environment. This is a critical scoping distinction.
In lm(y ~ . - z, data = d), the dot expands to every column in d except the response variable y. That gives you x, z, and w. Then - z removes z from the predictor set. The result is that only x and w serve as predictors — making A the correct answer. The external object q is never considered because the dot is bounded by data = d.
B is wrong because it assumes the dot reaches into the calling environment to find q. It does not — the dot is strictly scoped to the data frame supplied to data. C is wrong because it includes y as a predictor. y appears on the left side of the ~, designating it as the response, so it is automatically excluded when the dot expands. D is wrong because the dot selects all remaining columns, not just one. There is no rule that selects only the "first" predictor.
A useful rule of thumb: always mentally substitute the dot with "all columns in the data frame," then apply any subtractions. Never let the dot cross the boundary of the data argument — outside variables simply don't exist to the formula.
- Which description best characterizes the model columns generated by this formula under ordinary R contrast handling?
Answer: Three group indicator columns and one column for x, with no intercept.
When you see a formula with 0 + (or equivalently - 1) in R, your first instinct should be: the intercept has been suppressed. This fundamentally changes how R encodes factor variables in the design matrix.
Normally, R uses treatment contrasts for factors — one reference level is absorbed into the intercept, and the remaining levels become deviation columns. But when you remove the intercept with 0 +, R has no baseline to absorb, so it expands each factor level into its own full indicator (dummy) column. For a three-level factor like group with levels A, B, and C, that means three separate 0/1 columns — one for each level. The numeric variable x then contributes a single column as usual, giving you four total columns: groupA, groupB, groupC, and x. That's exactly what B describes.
A is wrong because it describes the default intercept parameterization — one intercept plus two contrast columns — which is what you'd get with lm(y ~ group + x), not lm(y ~ 0 + group + x). C is wrong on two counts: it incorrectly implies three separate slopes for x (that would require an interaction term like group:x), and its column count doesn't match the formula. D is a misunderstanding of how R handles factors; no levels are "omitted" here — suppressing the intercept adds a column rather than removing one.
A helpful rule of thumb: **0 + with a factor trades one intercept for one extra group column**, giving you full-rank indicator encoding instead of contrast encoding.
- Holding
x2 at 4, what change in the fitted response is associated with a one-unit increase in x1? Answer: The fitted response does not change.
When a model includes an interaction term like x1 * x2, the effect of x1 on the response is no longer a single fixed number — it depends on the value of x2. Specifically, the marginal effect of x1 is βx1+βx1:x2⋅x2. This is the core concept being tested here.
Plugging in the given values, the effect of a one-unit increase in x1 when x2 = 4 is 2+(−0.5)(4)=2−2=0. The fitted response does not change — making C the correct answer.
A is tempting because 2 is literally the coefficient printed next to x1 in the model summary. But that coefficient only represents the effect of x1 when x2 = 0, not at arbitrary values of x2. Using it directly here ignores the interaction entirely.
B mistakes the interaction coefficient −0.5 for the total effect of x1. The interaction coefficient alone tells you nothing about the marginal effect of x1; it only scales how that effect changes across values of x2.
D arrives at 4 — the value of x2 itself — with no clear mathematical basis. It likely reflects confusion about what role x2 = 4 plays in the calculation.
As a study tip: whenever you see an interaction term, immediately rewrite the marginal effect formula before plugging in numbers. Writing out ∂x1∂y^=βx1+βx1:x2⋅x2 explicitly will prevent you from mistakenly reading the coefficient table at face value. - Which formula describes the updated model?
Answer: log(y) ~ x + g + z, preserving the response and removing only the interaction.
When working with update() in R, think of the dot (.) as a placeholder meaning "whatever was already there." The syntax . ~ . means "keep the left-hand side as-is, keep the right-hand side as-is, then apply modifications." Understanding this placeholder behavior is the key to this question.
In the original model, the formula is log(y) ~ x * g, which R expands internally to log(y) ~ x + g + x:g. When you call update(fit, . ~ . - x:g + z), the left dot preserves log(y), the right dot preserves x + g + x:g, then -x:g removes only the interaction term, and +z adds the new predictor. The result is log(y) ~ x + g + z, making D the correct answer.
A is wrong because it claims the dot prevents term removal — the opposite is true. The dot expands the existing formula first, and then modifications like -x:g are applied on top of it.
B is wrong on two counts: the left-side dot does not strip transformations — it preserves log(y) exactly. There is no mechanism in update() that restores an untransformed response.
C reflects a common misunderstanding about how R handles hierarchy. Removing x:g with -x:g targets only the interaction term, not its component main effects x and g. Those remain in the model unless you explicitly remove them with -x -g.
As a study tip, remember: update() modifies, never resets. The dot is a copy, and each +/- term is a surgical edit on that copy.
- How is the left side of this formula interpreted by the binomial model?
Answer: As a success-count and failure-count response for each observation.
When you see cbind() on the left side of a glm formula with family = binomial, your brain should immediately shift into "grouped binomial" mode. This is R's way of supplying both pieces of binomial trial information — how many times you succeeded and how many times you failed — for each row of data.
In this setup, cbind(wins, losses) creates a two-column matrix where each row encodes a complete binomial experiment: wins gives the number of successes and losses gives the number of failures. R interprets this as a response with n=wins+losses trials and k=wins successes per observation. The model then estimates the log-odds of winning as a function of dose. That's exactly what D describes — a success-count and failure-count response — making it the correct answer.
A is wrong because cbind() here defines a single response (a binomial outcome), not two separate continuous responses being modeled simultaneously. B has the relationship completely backwards: dose is the predictor on the right side of ~, not the response. C is a tempting trap — you might think R quietly computes wins / losses as a ratio before fitting, but it doesn't. R retains the raw counts so it knows the total number of trials, which is essential for correct likelihood computation. A pre-computed ratio would discard that information entirely.
The pattern to remember: cbind(successes, failures) on the left of a binomial glm formula always means "grouped binary data," not a ratio, not dual responses, and not swapped roles. - Which formula most directly specifies the intended model?
Answer: y ~ x + I(x^2), because I() protects arithmetic inside the formula from special formula interpretation.
When writing formulas in R, you need to understand that operators like +, *, :, and ^ have special formula meanings that differ from their arithmetic meanings. The formula language uses these symbols to describe model structure, not math — so x^2 doesn't mean "x squared"; it means "x crossed with itself up to degree 2," which R interprets as just x alone.
The I() function — standing for "as-Is" — is R's escape hatch. Anything inside I() is evaluated as pure arithmetic, bypassing formula interpretation entirely. So I(x^2) genuinely computes the square of each value of x and hands that numeric vector to the model matrix as a distinct column. Writing y ~ x + I(x^2) gives you exactly two raw columns: one for x and one for x2. That makes B the correct answer.
A fails because inside a formula, x^2 uses the crossing operator ^, which expands interactions up to degree 2 — but since there's only one variable, it simply returns x. No squared column is added; you get the same model as y ~ x.
C is also wrong: x:x is the interaction of x with itself, which R reduces to just x again. An interaction of identical terms doesn't produce a power.
D is tempting but incorrect. poly(x, 2) by default returns orthogonal polynomials, not raw x and x2 columns. You'd need poly(x, 2, raw = TRUE) for raw columns.
Study tip: Whenever you need arithmetic inside a formula, reach for I(). Think of it as "I mean this mathematically."