使用%>%管道结合lm拟合分组线性模型时的报错问题求助
解决dplyr管道调用lm的错误,以及分组拟合添加拟合结果列的方法
首先来说你遇到的错误问题:你用Z %>% filter(d == 1) %>% lm(y ~ t)报错,本质是管道的参数传递逻辑和lm的参数顺序不匹配。
lm的标准调用格式是lm(formula, data, ...),第一个参数是公式,第二个才是数据框。而管道%>%默认会把左边的输出作为右边函数的第一个参数传入,所以你的代码相当于执行了lm(过滤后的Z数据框, y ~ t)——这就把数据框当成了lm的公式参数,把公式当成了data参数,lm试图把公式转成数据框,自然就抛出了那个错误。
修复单组拟合的代码
只要明确指定data参数为管道传来的数据(用.指代)就可以解决:
Z %>% filter(d == 1) %>% lm(y ~ t, data = .)
实现你的核心需求:分组拟合并添加拟合结果列
既然你需要针对d的每个因子水平分别拟合模型,还得把拟合值加回原数据框,用dplyr的分组操作更高效。这里直接用group_by()结合mutate()就能完成,不用手动拆分数据:
library(dplyr) # 先构造你的数据框(方便复现) Z <- data.frame( t = c(0, 1, 2, 0, 1, 2), x = c(1, 2, 3, 1, 2, 3), y = c(2, 3, 4, 2, 3, 4), d = factor(c(1, 1, 1, 2, 2, 2)) ) # 分组拟合,添加拟合值列fitted_y Z_with_fitted <- Z %>% group_by(d) %>% mutate(fitted_y = predict(lm(y ~ t, data = cur_data()))) %>% ungroup() # 查看结果 print(Z_with_fitted)
这段代码的逻辑是:
group_by(d):按d的不同水平把数据拆分成独立的分组mutate(...):对每个分组分别拟合y ~ t的线性模型,然后用predict()得到每个观测的拟合值,作为新列fitted_y添加进去cur_data():指代当前分组的数据框,避免作用域混淆(也可以用.代替,效果一样)
运行后你会看到,新的fitted_y列和原y列完全一致——因为你的数据里y和t是完美线性关系(y = t + 2),拟合结果完全贴合原始数据。
内容的提问来源于stack exchange,提问作者Pascal
相关产品推荐
相关产品推荐

