Multiple Linear Regression in R: Several Predictors

Model a numeric outcome from several predictors with lm(), interpret each coefficient holding the others constant, and decide which predictors actually matter — the practical way

Biostatistics

Learn multiple linear regression in R — model a numeric outcome from several predictors with lm(). Interpret each coefficient (the effect of one predictor holding the others constant), read R² and the F-test, drop predictors that don’t contribute, and predict new values.

Published

June 23, 2026

Modified

July 7, 2026

TipKey takeaways
  • Multiple linear regression models a numeric outcome from several predictors at once: outcome = b0 + b1·x1 + b2·x2 + ….
  • Fit it with lm(outcome ~ x1 + x2 + x3, data = ...) and read the summary.
  • Each coefficient is the effect of that predictor holding the others constant — the key difference from running separate simple regressions.
  • always rises with more predictors; use adjusted R² to compare models, and the per-predictor t-tests to see which predictors actually contribute.
  • Drop predictors that aren’t significant, re-check adjusted R², then predict() new values.

Introduction

Multiple linear regression extends simple linear regression to several predictors, so you can model an outcome that depends on more than one thing — and, crucially, isolate the effect of each predictor while holding the others constant.

The scenario: a company splits its advertising budget across youtube, facebook and newspaper, and wants to know which channels actually drive sales — and by how much, controlling for the others. A multiple regression answers exactly that.

The data: three advertising channels

We use the marketing dataset from datarium — the budget (in thousands of dollars) spent on youtube, facebook and newspaper, and the resulting sales, for 200 campaigns:

data("marketing", package = "datarium")
head(marketing, 4)
  youtube facebook newspaper sales
1  276.12    45.36     83.04 26.52
2   53.40    47.16     54.12 12.48
3   20.64    55.08     83.16 11.16
4  181.80    49.56     70.20 22.20

Fit the model

Add predictors with +. lm() fits the model; summary() reports the full output:

data("marketing", package = "datarium")

model <- lm(sales ~ youtube + facebook + newspaper, data = marketing)
summary(model)

Call:
lm(formula = sales ~ youtube + facebook + newspaper, data = marketing)

Residuals:
     Min       1Q   Median       3Q      Max 
-10.5932  -1.0690   0.2902   1.4272   3.3951 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  3.526667   0.374290   9.422   <2e-16 ***
youtube      0.045765   0.001395  32.809   <2e-16 ***
facebook     0.188530   0.008611  21.893   <2e-16 ***
newspaper   -0.001037   0.005871  -0.177     0.86    
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 2.023 on 196 degrees of freedom
Multiple R-squared:  0.8972,    Adjusted R-squared:  0.8956 
F-statistic: 570.3 on 3 and 196 DF,  p-value: < 2.2e-16

Interpret the full output

Read the summary piece by piece — every coefficient is an effect adjusted for the other predictors:

  • youtube slope = 0.046 — each extra 1 k$ on youtube adds 0.046 to sales, holding facebook and newspaper fixed. Highly significant (p < 2e-16).
  • facebook slope = 0.189 — each extra 1 k$ on facebook adds 0.189 to sales, the strongest channel per dollar, also highly significant.
  • newspaper slope = −0.001 — essentially zero and not significant (p = 0.86). Once youtube and facebook are in the model, newspaper adds nothing. (A simple regression of sales on newspaper alone looks positive — because newspaper budgets correlate with the others; controlling for them removes the illusion.)
  • R² = 0.897 / adjusted R² = 0.896 — the model explains ~90% of the variation in sales, a big jump over youtube alone (61%).
  • F-statistic F(3, 196) = 570, p < 2e-16 — the model as a whole is highly significant.
Note

Each coefficient is a partial effect. “Holding the others constant” is what separates multiple regression from three separate simple regressions — it’s why newspaper’s apparent effect vanishes here.

See the coefficients at a glance

A coefficient plot (estimate ± 95% CI) makes the story obvious — youtube and facebook sit clearly above zero, newspaper straddles it:

library(ggpubr)
library(broom)

data("marketing", package = "datarium")
model <- lm(sales ~ youtube + facebook + newspaper, data = marketing)

est <- tidy(model, conf.int = TRUE)
est <- est[est$term != "(Intercept)", ]

ggdotchart(est, x = "term", y = "estimate",
           add = "segments", rotate = TRUE, sorting = "descending",
           color = "#3a86d4", dot.size = 6,
           ggtheme = theme_pubr()) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "grey50") +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high), width = 0.2,
                color = "#3a86d4")

A coefficient plot of the three advertising predictors with 95% confidence intervals: youtube and facebook are clearly above zero, newspaper is centred on zero.

Confidence intervals

confint() gives the plausible range for each coefficient. Newspaper’s interval includes 0 — the sign that it doesn’t contribute:

data("marketing", package = "datarium")
model <- lm(sales ~ youtube + facebook + newspaper, data = marketing)

confint(model)
                  2.5 %     97.5 %
(Intercept)  2.78851474 4.26481975
youtube      0.04301371 0.04851558
facebook     0.17154745 0.20551259
newspaper   -0.01261595 0.01054097

Simplify: drop the predictor that doesn’t help

Newspaper is non-significant, so refit without it and compare. The adjusted R² barely changes — a simpler model that fits just as well:

data("marketing", package = "datarium")

model2 <- lm(sales ~ youtube + facebook, data = marketing)
summary(model2)$adj.r.squared        # ≈ 0.896, unchanged
[1] 0.8961505
anova(model2, lm(sales ~ youtube + facebook + newspaper, data = marketing))
Analysis of Variance Table

Model 1: sales ~ youtube + facebook
Model 2: sales ~ youtube + facebook + newspaper
  Res.Df    RSS Df Sum of Sq      F Pr(>F)
1    197 801.96                           
2    196 801.83  1   0.12775 0.0312 0.8599

The anova() F-test comparing the two models is non-significant (p = 0.86) — keeping newspaper does not improve the fit, so the two-predictor model is preferred (simpler, same explanatory power).

Predict new values

Use predict() on the chosen model to estimate sales for a new budget split:

data("marketing", package = "datarium")
model2 <- lm(sales ~ youtube + facebook, data = marketing)

new <- data.frame(youtube = 200, facebook = 40)
predict(model2, newdata = new, interval = "confidence")
       fit      lwr      upr
1 20.17605 19.83156 20.52055

A campaign spending 200 k$ on youtube and 40 k$ on facebook is predicted to sell ~20 units.

Report

A multiple linear regression predicted sales from youtube, facebook and newspaper advertising budgets. The model was significant, F(3, 196) = 570, p < 0.001, explaining 90% of the variance (adjusted R² = 0.90). youtube (b = 0.046, 95% CI 0.043–0.049, p < 0.001) and facebook (b = 0.189, 95% CI 0.172–0.206, p < 0.001) were significant positive predictors; newspaper was not (p = 0.86).

The model is \(y = \beta_0 + \beta_1 x_1 + \dots + \beta_p x_p + \varepsilon\). Least squares chooses the coefficients to minimise \(\sum_i (y_i - \hat{y}_i)^2\); in matrix form \(\hat{\boldsymbol\beta} = (X^\top X)^{-1} X^\top y\). Each \(\hat{\beta}_j\) is the effect of \(x_j\) adjusted for all other predictors. Adjusted R² penalises R² for the number of predictors \(p\), \(R^2_{adj} = 1 - (1 - R^2)\dfrac{n - 1}{n - p - 1}\), so it only rises when a new predictor earns its keep.

Check the assumptions

The same assumptions as simple regression — linearity, constant residual variance, normal residuals, no influential outliers — plus no severe multicollinearity between predictors. Base R’s plot(model) gives the diagnostic plots:

data("marketing", package = "datarium")
model <- lm(sales ~ youtube + facebook + newspaper, data = marketing)

par(mfrow = c(2, 2))
plot(model)

The four base-R regression diagnostic plots for the multiple regression model: residuals vs fitted, normal Q-Q, scale-location, and residuals vs leverage.

par(mfrow = c(1, 1))

See assumptions & diagnostics for how to read and fix each one, and multicollinearity & VIF for checking that predictors aren’t too correlated with each other.

Try it live

Drop or add a predictor and watch the adjusted R² and coefficients change. The sandbox boots on first Run.

🟢 With an AI agent

Ask Prova “fit a multiple regression on my data, interpret each coefficient holding the others constant, and tell me which predictors to keep” — it answers with code you can run and walks you through the output. The runtime is the judge. Ask Prova →

Common issues

You interpreted a coefficient without “holding the others constant.” In multiple regression every slope is a partial effect — the change in the outcome per unit of that predictor with the other predictors fixed. It can differ in size, or even sign, from the simple-regression slope.

You compared models with R² instead of adjusted R². Plain R² never decreases when you add a predictor, so it always favours the bigger model. Use adjusted R² (or anova() / AIC) to compare — it only rewards predictors that genuinely help.

A predictor flipped sign or lost significance when you added another. That’s multicollinearity or confounding — the predictors share information. It’s expected (newspaper here); check VIF when it’s severe.

Frequently asked questions

Each coefficient is the expected change in the outcome for a one-unit increase in that predictor, holding all other predictors constant. For sales ~ youtube + facebook, the youtube coefficient is the effect of youtube budget at a fixed facebook budget — a partial, adjusted effect, not the raw relationship.

R² is the share of variance explained; it always increases when you add a predictor, even a useless one. Adjusted R² penalises the number of predictors, so it only goes up when a new predictor improves the model more than chance would. Use adjusted R² to compare models of different sizes.

Start from the full model, look at each predictor’s t-test p-value, and drop non-significant ones, re-checking adjusted R² and an anova() model comparison each time. Keep predictors that are significant or that you have a substantive reason to control for. (Automated selection — stepwise, penalized — belongs to predictive modelling in the Machine Learning pillar.)

Because the predictors are correlated: once you control for one, the other’s unique contribution can shrink to nothing (newspaper here). This is the whole point of multiple regression — it shows the effect adjusted for the others. When predictors are highly correlated, check multicollinearity / VIF.

Test your understanding

  1. Run it. In the live cell, fit sales ~ youtube + facebook + newspaper, then sales ~ youtube + facebook. Does dropping newspaper change the adjusted R²?
  2. Conceptual. A simple regression gives newspaper a significant positive slope, but in the multiple model newspaper is non-significant. Which result describes newspaper’s real contribution to sales, and why?

Fill the blank with newspaper, then refit without it. Compare the Adjusted R-squared lines. For question 2, remember that the multiple-model coefficient is the effect holding the other channels constant.

lm(sales ~ youtube + facebook + newspaper, data = marketing)  # newspaper p = 0.86
lm(sales ~ youtube + facebook, data = marketing)              # adj R² ≈ 0.896, unchanged

Dropping newspaper leaves adjusted R² essentially unchanged — it contributes nothing. For question 2: the multiple-regression result describes newspaper’s real contribution. Its simple-regression slope is positive only because newspaper budgets correlate with youtube/facebook spending; once you control for those channels, newspaper’s own effect is zero.

TipWhich model when?

Conclusion

You can now run multiple linear regression in R: fit several predictors with lm(outcome ~ x1 + x2 + x3), interpret each coefficient as a partial effect holding the others constant, compare models with adjusted R² and anova(), drop predictors that don’t earn their place, and predict() new values. It’s the workhorse of applied modelling — and the base for categorical predictors, interactions, and diagnostics.

Reuse

Citation

BibTeX citation:
@online{2026,
  author = {},
  title = {Multiple {Linear} {Regression} in {R:} {Several}
    {Predictors}},
  date = {2026-06-23},
  url = {https://www.datanovia.com/learn/biostatistics/regression/multiple-linear-regression-in-r},
  langid = {en}
}
For attribution, please cite this work as:
“Multiple Linear Regression in R: Several Predictors.” 2026. June 23. https://www.datanovia.com/learn/biostatistics/regression/multiple-linear-regression-in-r.