如何按Item分组对Year与Value做线性回归并提取参数?
问题原因与解决方法
你的代码核心问题是**lm函数中指定了全局数据集df**,导致分组操作完全失效——不管怎么分组,lm(value ~ year, data=df)始终用整个原始数据集拟合回归,所以所有item的系数结果完全相同。
1. 正确实现分组+单独回归的方法
方法一:基础dplyr实现(无需额外包)
在group_by之后,summarise中调用lm时不要指定data=df,lm会自动识别当前分组的子数据集:
library(dplyr) df %>% group_by(item) %>% summarise( intercept = coef(lm(value ~ year))["(Intercept)"], slope = coef(lm(value ~ year))["year"], .groups = "drop" # 取消分组状态,输出普通数据框 )
如果想避免重复拟合模型(提升效率),可以先把模型存为列表,再批量提取系数:
df %>% group_by(item) %>% summarise( model = list(lm(value ~ year)), .groups = "drop" ) %>% mutate( intercept = sapply(model, function(x) coef(x)["(Intercept)"]), slope = sapply(model, function(x) coef(x)["year"]) ) %>% select(-model)
方法二:用broom包简化系数提取(推荐)
broom包的tidy()函数可以直接把模型输出转为整洁的数据框,信息更完整:
library(dplyr) library(broom) df %>% group_by(item) %>% summarise(tidy(lm(value ~ year)), .groups = "drop")
输出结果会包含每个item的截距、斜率的估计值、标准误、t值和p值,便于后续分析。
关键原理
在dplyr的分组操作中,summarise/mutate的执行环境是当前分组的子数据集,直接引用列名(如year、value)或使用cur_data()获取当前组数据,才能让lm针对每组单独拟合模型。
内容的提问来源于stack exchange,提问作者BoTz
相关产品推荐
相关产品推荐

