Site icon Ampersand Tutorials

Interaction Effects in Regression: Moderation, Simple Slopes, and What Not to Say

Two diverging lines crossing over a shared axis

Does the intervention work better for older patients? Does the effect of training depend on prior experience? Does the association between dose and response differ by sex? Each of these asks whether the effect of one variable changes across levels of another, and each is an interaction question.

An interaction is not an exotic add-on. When one exists, a model with only main effects is not a simplified description of the data — it is a description of a situation that does not exist, in which every group responds identically.

What an interaction actually is

Additivity assumes the effect of X on Y is the same at every level of Z. An interaction relaxes that: the difference in Y for a one-unit change in X is allowed to depend on where Z sits.

Y = b0 + b1·X + b2·Z + b3·(X×Z) + e

The product term carries the interaction. When b3 is zero, the model reduces to two additive effects. When b3 is non-zero, the effect of X is b1 + b3·Z, a line rather than a number — and that is precisely the point that gets lost in most write-ups.

ModelEffect of XWhat it claims
Y ~ X + Zb1, constantX works the same way at every level of Z
Y ~ X * Zb1 + b3·ZThe effect of X changes linearly with Z

The main effects stop meaning what you think

In a model with X, Z and X×Z, the coefficient b1 is the effect of X when Z equals exactly zero. If Z is a rating scale from 1 to 7, or age in years, or a centred variable, that conditional effect may describe nobody in the sample and may sit far outside the observed range.

This is the single most common reporting error in interaction analyses: presenting b1 as the main effect of X, and b2 as the main effect of Z, when both are conditional effects at a value of the other variable that may be arbitrary.

Two habits prevent it. First, centre continuous predictors, which moves zero to the mean and makes the conditional effect interpretable as an average effect. Second, describe what the interaction implies rather than reading coefficients off the table in isolation.

# R
dat$x_c <- dat$x - mean(dat$x)
dat$z_c <- dat$z - mean(dat$z)
fit <- lm(y ~ x_c * z_c, data = dat)
coef(summary(fit))

Centring does not change the interaction coefficient, the model fit, or any p-value associated with b3. It changes only the interpretation of the lower-order terms, which is exactly what you want.

Categorical by continuous: simple slopes

The most common design has one categorical moderator, such as treatment group, and one continuous predictor. Here the interaction tests whether the slope of the continuous predictor differs between groups.

fit <- lm(outcome ~ age_c * group, data = trial)
Anova(fit, type = 3)          # car: test the interaction term

library(emmeans)
emtrends(fit, ~ age_c | group)   # slope of age within each group
# Python
import statsmodels.formula.api as smf
from statsmodels.stats.anova import anova_lm

fit = smf.ols("outcome ~ age_c * group", data=trial).fit()
print(anova_lm(fit, typ=3))

Simple slopes are the deliverable. For each group, report the slope of the predictor with its confidence interval, because a reader wants to know what the model says happens within the group they care about — not the algebraic significance of a product term.

Categorical by categorical: differences of differences

With two categorical predictors the interaction asks whether the group difference in the outcome differs across levels of the other factor. In a 2×2 design this is a difference of differences, and it is worth reporting as such rather than as four coefficients against a reference cell.

library(emmeans)
emm <- emmeans(fit, ~ treatment | sex)
contrast(emm, method = "pairwise")   # treatment effect within each sex

Cells with few observations deserve a warning here. A difference of differences computed from a cell of four people will have a very wide interval, and the temptation to interpret it anyway is strong because it is the comparison the study was designed around.

Testing order matters

When an interaction is present, testing main effects before it answers a question nobody asked: whether the average effect across levels is zero, a quantity that can be zero even when the variable matters enormously in opposite directions in different groups.

Test the interaction first. If it is not supported, main effects interpreted as average effects are usually reasonable. If it is supported, move to simple slopes and report them instead of leaning on the omnibus test.

Interaction test resultWhat to report
Not significantMain effects as average effects, with the caveat that no moderation was detected
SignificantSimple slopes within each level of the moderator, with intervals
Significant but impreciseSimple slopes plus an explicit statement that the study was not powered to resolve them

Where the effect changes sign: Johnson-Neyman

With a continuous moderator, the effect of X may be positive at low values of Z and negative at high values. Reporting a single conditional effect at the mean hides that entirely.

library(interactions)
sim_slopes(fit, pred = x_c, modx = z_c, plot = TRUE)
johnson_neyman(fit, pred = x_c, modx = z_c)

The Johnson-Neyman procedure finds the range of the moderator where the effect is statistically distinguishable from zero, and the range where it is not. It is far more informative than picking arbitrary points such as one standard deviation above and below the mean, though those are acceptable when the region boundaries fall outside the observed data.

Power: the reason interactions disappoint

Interaction effects are typically much smaller than main effects, and detecting a product term requires substantially more data than detecting either component. A study powered to detect a main effect is usually underpowered for the interaction that would qualify it.

This has a practical consequence for interpretation: a non-significant interaction is weak evidence of no moderation, especially when the confidence interval around the product term is wide. Report that interval. An interaction coefficient of 0.05 with a 95% interval from -0.30 to 0.40 is not evidence of absence.

It also explains a literature-wide pattern. Interactions that replicate reliably tend to be large by the standards of the field, and many published interaction findings are best read as underpowered estimates of small effects.

Assumptions and diagnostics still apply

A product term does not exempt the model from the usual checks. Interactions are especially sensitive to influential points, because a handful of observations at the extremes of both predictors can create an apparent product effect that vanishes when they are removed.

plot(fit, which = 5)     # residuals vs leverage
car::influenceIndexPlot(fit)

Check whether the interaction survives a refit without the most influential observations. If it does not, that is a finding worth reporting rather than a problem to be fixed by deletion.

What to report

Give the full model specification, state whether continuous predictors were centred and at what value, report the interaction estimate with its confidence interval and the test used, and then give simple slopes with intervals for each level of the moderator. Say explicitly which coefficient is conditional and on what. Name the range of the moderator over which the effect is distinguishable from zero.

Moderation is closely related to mediation — one asks when an effect holds, the other asks how it is transmitted — and both sit within the wider family of models for conditional and indirect effects. Ampersand Academy works through those designs in more depth.

Practice

  1. Fit a model with and without a product term and compare the interaction estimate with its confidence interval.
  2. Centre both predictors, refit, and explain how the interpretation of the lower-order coefficients changed.
  3. Compute simple slopes at three values of the moderator and state which are distinguishable from zero.
  4. Locate the Johnson-Neyman boundaries and describe the region where the effect is undetectable.

What is the difference between an interaction and a main effect?

A main effect is the average effect of a predictor across levels of the others. An interaction means that effect differs by level: the effect of X depends on Z. When an interaction is present, the main effect describes an average that may not hold for any actual group.

Should I centre variables before testing an interaction?

Centring does not change the interaction coefficient, the fit, or any p-value. It changes what the lower-order coefficients mean, moving the reference from zero to the mean, which makes them interpretable as average effects. Do it for interpretation, not for statistical reasons.

Why did my main effect become non-significant when I added an interaction?

Because the main effect is now conditional at the other variable equal to zero. If zero is outside the data range, that coefficient describes nobody and can lose significance while the variable still matters. Centre the moderator and interpret simple slopes instead.

How many observations do I need to detect an interaction?

Substantially more than for a main effect, often several times as many, because interaction effects are usually smaller and the product term is correlated with its components. A study powered for main effects is typically underpowered for the interaction.

What are simple slopes?

The effect of the predictor estimated separately at specific values of the moderator, each with its own confidence interval. They replace the single interaction coefficient in reporting, because readers want to know what happens within a group rather than the algebra of a product term.

What is the Johnson-Neyman technique?

A method that finds the range of the moderator over which the effect of the predictor is statistically distinguishable from zero, and the range where it is not. It avoids arbitrary choices such as plus or minus one standard deviation and is more informative for continuous moderators.

Does a non-significant interaction mean there is no moderation?

No. Interaction tests are usually underpowered, so a wide confidence interval crossing zero is weak evidence of absence. Report the interval and avoid concluding that the effect is the same everywhere just because the product term was not significant.

Exit mobile version