如何处理lm对象列表?investr包多分组逆回归实现问询
解决APD数据框按Serial_number批量逆回归的问题
我明白你现在的困扰:单个Serial_number子集用investr::invest()没问题,但处理整个数据集的模型列表时就卡壳了。别担心,咱们一步步来解决这个问题。
第一步:为每个Serial_number拟合模型并生成模型列表
首先,咱们需要把原始数据按Serial_number拆分,然后为每个子集拟合线性模型。这里用基础R的split()和lapply()就能搞定:
# 加载需要的包 library(investr) # 按Serial_number拆分数据框 apd_by_serial <- split(APD, APD$Serial_number) # 为每个子集拟合Amplification ~ Voltage的线性模型 model_list <- lapply(apd_by_serial, function(sub_df) { lm(Amplification ~ Voltage, data = sub_df) })
这里要注意:model_list是一个lm对象的列表,每个元素对应一个Serial_number的模型。之前你用models[1]出错,大概率是因为models[1]返回的是长度为1的列表,而invest()需要的是单个lm对象——你应该用model_list[[1]]来提取第一个模型(双重方括号才会取出列表里的实际lm对象)。
第二步:批量执行逆回归
接下来,咱们用lapply()遍历模型列表,对每个模型调用invest(),指定y0=150:
# 批量计算每个模型的逆回归结果 inverse_results <- lapply(model_list, function(mod) { # 这里可以根据需求调整interval参数,比如选"prediction"预测区间 invest(mod, y0 = 150, interval = "confidence") })
执行完后,inverse_results里每个元素都是对应Serial_number的逆回归结果,包含估计值、置信区间等信息。
第三步:整理结果为可读的数据框
如果想把结果整理成更直观的数据框,可以用下面的代码:
# 将结果合并为数据框 final_results <- do.call(rbind, lapply(names(inverse_results), function(serial) { res <- inverse_results[[serial]] data.frame( Serial_number = serial, Estimated_Voltage = res$estimate, Lower_Confidence_Limit = res$conf.int[1], Upper_Confidence_Limit = res$conf.int[2] ) })) # 查看结果 print(final_results)
替代方案:用tidyverse工具链更简洁处理
如果你习惯用tidyverse的话,用dplyr分组+nest+purrr::map的方式会更流畅,全程在数据框里操作:
library(dplyr) library(tidyr) library(purrr) tidy_results <- APD %>% # 按Serial_number分组 group_by(Serial_number) %>% # 将每组数据嵌套成列表列 nest() %>% # 为每组数据拟合模型 mutate(model = map(data, ~lm(Amplification ~ Voltage, data = .x))) %>% # 对每个模型执行逆回归 mutate(inverse_output = map(model, ~invest(.x, y0 = 150, interval = "confidence"))) %>% # 提取需要的结果字段 mutate( Estimated_Voltage = map_dbl(inverse_output, ~.x$estimate), Lower_CI = map_dbl(inverse_output, ~.x$conf.int[1]), Upper_CI = map_dbl(inverse_output, ~.x$conf.int[2]) ) %>% # 保留需要的列并取消分组 select(Serial_number, Estimated_Voltage, Lower_CI, Upper_CI) %>% ungroup() print(tidy_results)
关键注意点总结
- 别再用
models[1]了!要用models[[1]]提取单个lm对象,这是新手很容易踩的坑。 invest()本身不支持批量处理模型列表,必须用循环或apply类函数(lapply/map)来逐个处理。- 整理结果时,把分散的结果合并成数据框会大大方便后续的分析和可视化。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

