data("marketing", package = "datarium")
model <- lm(sales ~ youtube, data = marketing)
model
Call:
lm(formula = sales ~ youtube, data = marketing)
Coefficients:
(Intercept) youtube
8.43911 0.04754
After you fit a model, check it. Read the four diagnostic plots, test linearity, normality and homoscedasticity, and find outliers and influential points — with the fixes when an assumption fails
Check the assumptions of a linear regression in R: linearity, normality of residuals, homogeneity of variance (homoscedasticity), and influential observations. Read the four base-R diagnostic plots (residuals vs fitted, normal Q-Q, scale-location, residuals vs leverage), detect outliers, high-leverage and influential points with Cook’s distance — and the workaround for each violation. Run it all live.
June 23, 2026
July 8, 2026
plot(model) — check all of them: Residuals vs Fitted (linearity), Normal Q-Q (normality), Scale-Location (homoscedasticity), Residuals vs Leverage (influence).Fitting a linear regression is only half the job — a model can return a slope, an R² and a p-value while quietly violating the assumptions those numbers rely on. Regression diagnostics check whether the model actually fits the data, so you can trust the result (or fix it).
Linear regression assumes four things. This lesson shows how to check each one with R’s built-in diagnostic plots, how to read them, and — the practical part — what to do when an assumption fails.
We use the marketing dataset from datarium and fit a simple model predicting sales from the youtube advertising budget:
Call:
lm(formula = sales ~ youtube, data = marketing)
Coefficients:
(Intercept) youtube
8.43911 0.04754
The fitted line is sales = 8.44 + 0.0475 × youtube. Now let’s check whether this model is sound.
Two concepts underlie every diagnostic. The fitted (predicted) value is what the model expects for a given predictor; the residual is the gap between the observed value and that fitted value:
data("marketing", package = "datarium")
model <- lm(sales ~ youtube, data = marketing)
marketing$fitted <- fitted(model)
plot(marketing$youtube, marketing$sales, pch = 19, col = "grey40",
xlab = "YouTube budget (k$)", ylab = "Sales")
abline(model, col = "#3a86d4", lwd = 2)
segments(marketing$youtube, marketing$sales,
marketing$youtube, marketing$fitted, col = "red")
Each red segment is a residual error. The diagnostics that follow all examine the distribution of these residuals — if the model is right, the residuals should be patternless, evenly spread, and roughly normal. You can pull them out directly with base R:
data("marketing", package = "datarium")
model <- lm(sales ~ youtube, data = marketing)
diag <- data.frame(
fitted = fitted(model), # predicted sales
resid = residuals(model), # observed - fitted
std_resid = rstandard(model), # standardized residual (outlier check)
hat = hatvalues(model), # leverage (extreme predictor check)
cooksd = cooks.distance(model) # influence (Cook's distance)
)
head(diag, 4) fitted resid std_resid hat cooksd
1 21.564929 4.955071 1.2733486 0.009703067 0.007943433
2 10.977569 1.502431 0.3865746 0.012168549 0.000920434
3 9.420269 1.739731 0.4486150 0.016493630 0.001687550
4 17.081273 5.118727 1.3123012 0.005013546 0.004338753
plot(model) produces the four standard diagnostic plots at once — the fastest way to screen a model:

Read them as four checks:
Each plot labels the 3 most extreme observations by row number (#26, #36, #179 here) — worth a look, but not automatically a problem. The next sections take each assumption in turn.
Check the Residuals vs Fitted plot (plot 1). Ideally the red line is approximately horizontal at zero — a pattern signals that the straight-line model is wrong:

Verdict here: no strong pattern — the linearity assumption is reasonable. If it failed (a clear curve), the fix is a non-linear transformation of the predictor — log(x), sqrt(x), or a polynomial term poly(x, 2) — then re-check this plot.
Check the Scale-Location plot (plot 3). A horizontal line with evenly spread points means constant variance; an upward trend means the spread grows with the fitted value — heteroscedasticity:

Verdict here: the line trends up — the residual variance increases with predicted sales, so this model has a heteroscedasticity problem. The fix is a log or square-root transformation of the outcome:

After modelling log(sales), the scale-location line is much flatter — the variance is stabilised.
Check the Normal Q-Q plot (plot 2). If the residuals are normal, the points fall along the dashed reference line:

Verdict here: the points follow the line closely — normality is a safe assumption. With a large sample the F- and t-tests are robust to mild departures anyway; worry only about strong curving or heavy tails. If it failed, a transformation of the outcome often helps (and frequently fixes heteroscedasticity at the same time).
Two different kinds of extreme observation, read off the Residuals vs Leverage plot (plot 5):
p = number of predictors, n = observations).
Verdict here: the three labelled points (#26, #36, #179) have standardized residuals between −2 and −3 — extreme but none beyond ±3, so no genuine outliers. And every hat value is below 2(p + 1)/n = 4/200 = 0.02, so there are no high-leverage points either.
An influential point is one whose inclusion or exclusion would change the regression result. It combines leverage and residual size, measured by Cook’s distance — flagged when it exceeds 4/(n − p − 1). Plot Cook’s distance and Residuals vs Leverage side by side:

Inspect the highest-Cook’s-distance rows directly with base R:
youtube facebook newspaper sales
36 348.84 4.92 10.20 15.36
179 332.04 2.76 28.44 14.16
26 315.48 4.20 23.40 14.40
Verdict here: no influential points. The Cook’s-distance contour lines don’t even appear on the Residuals-vs-Leverage plot because every point sits comfortably inside them — excluding any single observation would barely move the fit.
To see the contrast, add two extreme points and refit — now the diagnostics light up:

Observations #201 and #202 sit far beyond the Cook’s-distance lines — they are influential. Excluding them shifts the slope (here from ~0.065 back toward ~0.048). When a point is both high-Cook’s-distance and at the edge of the leverage plot, decide deliberately: is it a data-entry error (fix or drop it) or a real, important observation (keep it, and report the sensitivity)?
| Assumption | Plot | Good sign | Fix if violated |
|---|---|---|---|
| Linearity | Residuals vs Fitted | flat red line | transform predictor: log(x), poly(x, 2) |
| Normality | Normal Q-Q | points on the line | transform outcome; large-n is robust |
| Homoscedasticity | Scale-Location | flat, even spread | transform outcome: log(y), sqrt(y) |
| No influence | Residuals vs Leverage + Cook’s | inside the contours | investigate / exclude the point |
The standardized residual is \(r_i = \dfrac{e_i}{s\sqrt{1 - h_i}}\), where \(e_i\) is the raw residual, \(s\) the residual standard error, and \(h_i\) the leverage (hat value). Leverage \(h_i\) is the \(i\)-th diagonal of the hat matrix \(H = X(X^\top X)^{-1}X^\top\), with \(\sum_i h_i = p + 1\) — hence the 2(p+1)/n rule (twice the average). Cook’s distance combines residual and leverage, \(D_i = \dfrac{r_i^2}{p + 1}\cdot\dfrac{h_i}{1 - h_i}\) — large when a point is both far from the line and extreme in the predictors.
Refit with the log of sales and re-run the diagnostics — does the scale-location plot flatten out? The sandbox boots on first Run.
Ask Prova “check the assumptions of my regression and tell me which one is violated and how to fix it” — it reads your diagnostic plots and answers with code you can run on your own model. The runtime is the judge. Ask Prova →
You treated a labelled point as an automatic outlier. plot(model) labels the 3 most extreme rows by default — that’s just “look here,” not “remove these.” Check the actual cut-offs: standardized residual > 3 (outlier), hat > 2(p+1)/n (leverage), Cook’s distance > 4/(n−p−1) (influence).
You saw a pattern in residuals and panicked. A pattern isn’t a stop signal — it’s information. A curve in Residuals-vs-Fitted suggests a transformation or a missing term; a funnel in Scale-Location suggests a log/sqrt outcome. Fix the model, don’t abandon it.
Heteroscedasticity with a valid model. If a transformation isn’t desirable, keep the model but use robust (heteroscedasticity-consistent) standard errors for inference (e.g. sandwich + lmtest), so the p-values and CIs stay valid.
Four: linearity (the predictor–outcome relationship is a straight line), independence of the residual errors, normality of the residuals, and homoscedasticity (constant residual variance). You also check for influential observations that distort the fit. All are diagnosed by examining the residuals.
Fit the model with lm(), then call plot(model) for the four diagnostic plots: Residuals vs Fitted (linearity), Normal Q-Q (normality), Scale-Location (homoscedasticity), and Residuals vs Leverage (influential points). Read each plot against its assumption; back them with rstandard(), hatvalues() and cooks.distance().
An outlier has a standardized residual (rstandard()) beyond ±3. A high-leverage point has a hat value (hatvalues()) above 2(p+1)/n. An influential point has a Cook’s distance (cooks.distance()) above 4/(n−p−1) — it’s the one that actually changes the fit when removed. The Residuals-vs-Leverage plot shows all three at once.
It depends which: non-linearity → transform the predictor (log, sqrt, poly); heteroscedasticity → transform the outcome (log(y), sqrt(y)) or use robust standard errors; non-normal residuals → transform the outcome (large samples are fairly robust); an influential point → investigate it (data error vs real) and report the analysis with and without it.
lm(sales ~ youtube) with lm(log(sales) ~ youtube). Which one shows constant variance?Fill the blank with sales, then log(sales), and watch the red line in the scale-location plot. For question 2, recall that Cook’s distance combines both residual size and leverage.
The log(sales) model has the more constant variance. For question 2: probably not influential. Cook’s distance multiplies residual size by leverage; a large residual at low leverage (a typical predictor value) gets little weight, so removing the point barely moves the line. Influence needs both an unusual outcome and an unusual predictor value.
You can now diagnose a linear regression in R: read the four plot(model) diagnostics, check linearity (Residuals vs Fitted), normality (Q-Q), homoscedasticity (Scale-Location), and influence (Residuals vs Leverage + Cook’s distance) — and apply the right fix for each violation, from transforming a variable to handling an influential point. A model you’ve checked is a model you can report.
Prove you can do it. Master the whole Regression in R series — track your path, build projects, and earn a certificate.
Go Pro — unlimited Prova on your own data and a verifiable certificate that proves the skill.
from $15/mo billed yearly
✓ You're Pro — keep going. The runtime is the judge.
Get new R & Python lessons by email
Practical, reproducible, no spam. Unsubscribe anytime.
Double opt-in. We never share your email.
Every result on this page was produced by the code shown, run at build time against a pinned R environment — edit any block and Run to reproduce it yourself.
@online{2026,
author = {},
title = {Linear {Regression} {Assumptions} and {Diagnostics} in {R}},
date = {2026-06-23},
url = {https://www.datanovia.com/learn/biostatistics/regression/linear-regression-assumptions-and-diagnostics-in-r},
langid = {en}
}