线性回归是统计建模中最基础也最常用的方法之一。R语言内置的lm函数可以非常方便地拟合普通最小二乘模型,但真正用好它需要理解公式接口、系数输出和模型对象的结构。模型本身只是分析的一部分,残差诊断和影响点检查同样重要,很多时候模型不显著的原因并不在变量本身,而在于忽略了某些前提假设。

一、R语言线性回归的核心知识点与建模流程
lm函数的基本调用形式是lm(formula, data),其中formula用来描述变量关系,data指定数据框。以R自带的mtcars数据集为例,如果想研究汽车重量wt对每加仑行驶里程mpg的影响,可以写成mpg ~ wt。左侧是因变量,右侧是自变量,波浪号表示由右侧变量解释左侧变量。summary函数会给出完整的模型摘要。
# 拟合简单线性回归 model <- lm(mpg ~ wt, data = mtcars) summary(model)
summary输出的核心部分包括系数表、残差统计量、拟合优度和整体显著性检验。系数表中的Estimate是回归系数的估计值,Std. Error是标准误,t value是单个系数的t统计量,最后一列是对应的p值。如果某个自变量的p值小于0.05,通常认为该变量在统计上显著。Multiple R-squared表示模型解释的变异比例,Adjusted R-squared会考虑自变量个数进行惩罚,更适合多元回归比较。F统计量用来检验所有自变量是否联合显著,如果F检验的p值很小,说明模型整体有效。
实际建模中很少只用单个自变量。多元线性回归可以直接在公式右侧用加号连接多个变量。如果数据中包含分类变量,必须将其转换为因子类型,否则R会把它当作普通数值变量处理。factor函数可以在公式中直接完成转换。例如同时加入重量、马力和气缸数,可以写作mpg ~ wt + hp + factor(cyl)。
# 加入多个自变量和因子变量 model2 <- lm(mpg ~ wt + hp + factor(cyl), data = mtcars) summary(model2)
公式接口还支持交互项和变量变换。mpg ~ wt * hp表示同时包含wt、hp以及二者的交互项,等价于mpg ~ wt + hp + wt:hp。如果需要在公式中进行算术运算,比如对变量取对数或平方,可以使用I函数,例如mpg ~ wt + I(wt^2)。这样做可以避免公式解析器把运算符当作特殊符号。模型建立后,可以用coef提取系数,confint给出置信区间,fitted和residuals分别获取拟合值和残差,predict用于对新数据进行预测。这些函数返回的对象是后续诊断分析的基础。
# 提取模型系数、置信区间和预测值 coef(model) confint(model) predict(model, newdata = data.frame(wt = 3, hp = 110, cyl = factor(4)))
理解模型对象的结构对深入分析很有帮助。model是一个列表,包含coefficients、residuals、fitted.values、rank等组件。names(model)可以查看全部组件名称。通过直接访问这些组件,可以自定义计算各种统计量,比如手动计算残差平方和或绘制残差图,而不必完全依赖现成的诊断函数。
二、回归诊断的关键维度与R实现
线性回归建立在几个前提假设之上:线性关系、误差独立、同方差性、正态性和不存在强影响点。任何一个假设严重不满足,都会使系数估计和假设检验失去可靠性。R语言中plot函数可以直接对lm对象生成四幅诊断图,它们分别针对不同假设进行可视化检查。
# 生成模型诊断图 par(mfrow = c(2, 2)) plot(model) par(mfrow = c(1, 1))
第一幅图是残差与拟合值图,用来检查线性假设和同方差性。如果图上出现明显的曲线趋势,说明可能存在非线性关系;如果残差随拟合值增大呈喇叭状扩散,说明存在异方差。第二幅图是Q-Q图,如果点大致落在对角线上,说明残差接近正态分布。第三幅图是尺度位置图,也能反映异方差。第四幅图是残差与杠杆图,用来识别高杠杆点和强影响点,图中标注出来的点值得进一步检查。
除了图形判断,还可以用统计检验来辅助诊断。shapiro.test可以对残差进行正态性检验,原假设是数据服从正态分布。p值大于0.05时通常不拒绝正态假设,但样本量较大时该检验可能过于敏感。异方差可以通过car包中的ncvTest进行检验,原假设是误差方差恒定。多重共线性可以用vif函数计算方差膨胀因子,VIF值大于10通常被认为存在严重的共线性问题。
# 残差正态性检验 shapiro.test(residuals(model)) # 非恒定方差检验,需要car包 library(car) ncvTest(model) # 多重共线性检验 vif(model2)
影响点识别是回归诊断中容易忽略的环节。Cook距离综合了残差和杠杆信息,用来衡量某个观测对整体回归结果的影响程度。通常Cook距离超过4除以样本量的观测需要特别关注。杠杆值hatvalues表示每个观测对自身拟合值的影响,平均杠杆值为(p+1)/n,其中p为自变量个数。高杠杆点不一定是有问题的点,但如果同时残差很大,就可能对模型产生扭曲。可以暂时移除这些点重新建模,比较系数变化是否明显。
# 计算Cook距离和高杠杆值 cooksd <- cooks.distance(model2) which(cooksd > 4 / length(cooksd)) hatvalues(model2)
诊断的目的是发现潜在问题并改进模型,而不是机械地删点或变换变量。如果发现非线性趋势,可以尝试加入二次项或使用对数变换;如果存在异方差,可以考虑加权最小二乘或稳健标准误;如果多重共线性严重,可以删除相关性较高的变量或使用主成分回归。每一项调整都应该基于业务理解,避免过度拟合。
三、常见问题解答汇总
为什么lm函数提示变量长度不一致?
这种错误通常是因为公式中的变量来自不同数据对象,或者数据框中存在缺失值但不同列缺失位置不同。lm函数默认会删除包含缺失值的观测,但如果变量长度从根本上不一致,比如一个向量来自完整数据,另一个来自筛选后的子集,就会报错。解决办法是统一把变量放进同一个数据框,并确保每一列长度相同。可以使用complete.cases函数检查完整观测数量。
分类变量没有自动变成因子怎么办?
如果分类变量以数值编码存储,比如1代表对照组,2代表实验组,R会默认把它当作连续变量,从而错误地估计每增加一个单位的效应。必须在建模前或公式中将其转换为因子。除了factor函数,还可以用as.factor或者把数据框中的列提前转换为因子。转换后lm函数会自动生成虚拟变量,默认以第一个水平为参照组。
预测时为什么报错说newdata列名不存在?
predict函数要求newdata数据框中必须包含模型中用到的自变量,而且列名必须完全一致。一个常见的错误是原始数据中列名是wt,而新数据中写成了weight。另一个问题是分类变量的水平不一致,比如训练数据中因子水平是a和b,新数据中只出现了a。这时候需要确保新数据的因子水平与训练时相同,可以使用levels参数统一设置。
如何在公式中使用变量变换和交互项?
如果直接在公式中写mpg ~ log(wt),R会正确理解log函数。但如果写mpg ~ wt^2,公式解析器不会把它当作平方项,而是当作包含wt及其与自身交互的项,结果可能仍然是线性项加上多余项。正确做法是使用I函数包裹算术表达式,例如mpg ~ wt + I(wt^2)。交互项用冒号或星号,mpg ~ wt * hp会自动展开为主效应加交互项。
如何比较两个嵌套模型?
嵌套模型是指一个模型的自变量集合是另一个模型自变量集合的子集。可以用anova函数比较两个lm对象,例如model_a只包含wt,model_b包含wt和hp。anova会做F检验,原假设是新增变量不显著。如果p值小于0.05,说明复杂模型显著优于简单模型。这种方法常用于变量选择,但要注意比较的模型必须基于同一数据集。
# 比较两个嵌套模型 model_a <- lm(mpg ~ wt, data = mtcars) model_b <- lm(mpg ~ wt + hp, data = mtcars) anova(model_a, model_b)
除了上面这些常见问题,还需要注意lm函数对缺失值的默认处理。na.action选项默认是na.omit,会删除所有包含缺失值的行。如果数据集缺失较多,可能导致样本量大幅减少。此时可以考虑多重插补或使用其他缺失值处理方法。另外,模型结果中如果出现NA系数,通常意味着变量之间存在完全共线性,需要检查数据构造方式。
总体来看,R语言线性回归并不只是调用lm一个函数那么简单。从公式构建、模型拟合到诊断和问题排查,每一步都需要结合数据和业务背景进行判断。掌握这些核心知识点和常见问题的处理方法,可以让分析结论更加可靠。

