To run a linear regression in R, you fit the model with lm(outcome ~ predictor, data = df), read the coefficients, R-squared, and F test with summary(), and then check the four regression assumptions through the diagnostic plots before trusting a single number. Moving from one predictor to multiple regression is just adding terms to the formula, but it brings multicollinearity and model-comparison questions that the simple model never raised. This guide covers both with the code to keep.
Simple linear regression with lm()
Linear regression models a continuous outcome as a straight-line function of one or more predictors. Fit and read it with two lines:
model <- lm(score ~ hours, data = df)
summary(model)The Estimate for hours is the slope: the predicted change in score for each additional hour. The Pr(>|t|) column tests whether that slope differs from zero, Multiple R-squared is the proportion of variance explained, and the F statistic at the foot tests the model as a whole. Understanding what those p-values mean is covered in our p-value guide.
The assumptions and how to check them
Ordinary least squares assumes linearity, independent errors, constant error variance (homoscedasticity), and roughly normal residuals. R gives all four checks in one place:
par(mfrow = c(2, 2))
plot(model)
# Residuals vs Fitted: linearity and equal variance
# Normal Q-Q: residual normality
# Scale-Location: homoscedasticity
# Residuals vs Leverage: influential points (Cook's distance)The full reasoning behind each plot, and what a violation looks like, is set out in linear regression assumptions. Checking residuals rather than the raw variables is the same habit used in ANOVA in R.
Multiple regression: adding predictors
Add predictors with +, and an interaction with *:
model2 <- lm(score ~ hours + prior_gpa + motivation, data = df)
summary(model2)
# an interaction between two predictors
model3 <- lm(score ~ hours * motivation, data = df)In a multiple model each coefficient is the effect of that predictor holding the others constant, which is why a predictor can be significant alone yet drop out once related variables enter. Categorical predictors should be factors; R then creates the dummy variables automatically and reports each level against the reference.
Checking multicollinearity
When predictors are strongly correlated, their coefficients become unstable and hard to interpret. Quantify it with the variance inflation factor from the car package:
library(car)
vif(model2) # values above 5 (some say 10) signal a problemA high VIF means a predictor is largely explained by the others; the usual remedy is to drop or combine the redundant variables, not to keep them all and report unstable estimates.
Comparing and choosing models
To decide whether an added predictor earns its place, compare nested models with an F test, and compare non-nested models with AIC:
anova(model, model2) # is the larger model a real improvement?
AIC(model, model2) # lower AIC is betterResist adding predictors just to lift R-squared; the Adjusted R-squared in the summary penalizes that, and a model justified by theory beats one fitted by trial and error.
Reporting linear regression in APA style
Report the model fit as F(df1, df2) = value with its p and the R-squared, then each predictor as its unstandardized coefficient (b), standard error, and p-value, with a confidence interval from confint(model). A clean sentence reads: hours of study significantly predicted exam score, b = 2.13, 95% CI [1.40, 2.86], p < .001, with the model explaining 38% of the variance, R-squared = .38, F(3, 146) = 29.7, p < .001. The conventions sit in writing the result up in APA style, and the prose belongs in your results section of a research paper. When the outcome is binary rather than continuous, switch to logistic regression in R.