R语言lm模型调用predict()返回两组预测值完全相同问题排查
问题原因
报错和预测结果异常的核心诱因是lm()拟合时的变量写法错误:
你在模型公式中使用了sample$outcome ~ sample$index + sample$dummy这种带数据框$前缀的变量引用方式,会导致模型内部固定记录变量为全局环境下带sample$前缀的对象。后续调用predict()时,函数会在你传入的newdata中查找名为sample$index、sample$dummy的列,因为你传入的新数据列名是index、dummy,名称完全不匹配,函数就会直接忽略newdata,回退用拟合模型时的原始417行数据计算预测值。
这就是警告信息'newdata' had 17 rows but variables found have 417 rows的来源,你传入的dummy=0、dummy=1的设置根本没有参与预测计算,两个预测结果自然完全一致,长度也和原始数据框相同。
修正方案
只需要调整lm()的写法,通过data参数指定模型关联的数据框,公式内直接写列名、不要加数据框名$前缀即可,修正后的可运行代码如下:
index <- runif(417, min = 9, max = 25) outcome <- runif(417, min = 15, max = 100) sample <- data.frame(index,outcome) # 生成分组虚拟变量 sample$dummy <- ifelse(sample$index > 13, 1, 0) # 正确的模型拟合写法 fit <- lm(outcome ~ index + dummy, data = sample) # 生成处理组预测值 yT.hat <- predict(fit, newdata = data.frame(index = 9:25, dummy = 1)) # 生成对照组预测值 yC.hat <- predict(fit, newdata = data.frame(index = 9:25, dummy = 0))
修正后运行不会再弹出警告,返回的yT.hat和yC.hat长度均为17(对应index从9到25的17个取值),两个向量的差值等于模型中dummy变量的估计系数,符合分组预测的预期。
注意事项
- 编写R语言回归类函数的公式时,优先通过
data参数传入关联的数据框,不要在公式内写df$列名格式的引用。这种写法除了会导致predict()匹配变量失败,还会造成回归项名称异常,后续做系数提取、边际效应计算、回归可视化时都会出现匹配错误。
内容的提问来源于stack exchange,提问作者professor.luther.ratigan
相关产品推荐
相关产品推荐

