R语言如何从列表中筛选含多个预测变量的线性模型
提取线性模型列表中预测变量数大于1的模型
现有存储多个lm类线性模型的列表,需要筛选出预测变量数量大于1的模型,且保留模型完整属性(包含模型调用Call、类属性等)。
示例数据
require(faraway) lm1 <- lm(lifespan ~ brain, mammalsleep) lm2 <- lm(lifespan ~ brain+dream+nondream, mammalsleep) lm3 <- lm(lifespan ~ brain+sleep, mammalsleep) lm4 <- lm(lifespan ~ brain+predation+danger, mammalsleep) lm5 <- lm(lifespan ~ sleep, mammalsleep) list_models <- list(lm1, lm2, lm3, lm4, lm5)
原有尝试的问题
- 第一种方法错误:遍历到符合条件的模型时,直接返回了整个原始列表
list_models,导致结果出现大量重复冗余。
map(list_models, function(x)if(length(names(x$model))>2){ list_models })
- 第二种方法错误:
ifelse是向量化函数,会强制将输入的lm对象拆解为系数原子向量,丢失原模型的类属性、调用信息等内容,最终返回的不是完整模型对象。
true_false <-map(list_models, function(x)length(names(x$model))>2) models <- mapply(function(x, y)ifelse(y == TRUE, x, 0), list_models, a) %>% keep(~all(. != 0)) [[1]] (Intercept) brain dream nondream 23.89600096 0.01637543 -2.87404813 -0.28644022 [[2]] (Intercept) brain sleep 28.446910677 0.007815582 -1.051868346 [[3]] (Intercept) brain predation danger 21.364090058 0.008106425 -10.425407458 9.818648866
期望输出
[[1]] Call: lm(formula = lifespan ~ brain + dream + nondream, data = mammalsleep) Coefficients: (Intercept) brain dream nondream 23.89600 0.01638 -2.87405 -0.28644 [[2]] Call: lm(formula = lifespan ~ brain + sleep, data = mammalsleep) Coefficients: (Intercept) brain sleep 28.446911 0.007816 -1.051868 [[3]] Call: lm(formula = lifespan ~ brain + predation + danger, data = mammalsleep) Coefficients: (Intercept) brain predation danger 21.364090 0.008106 -10.425407 9.818649
正确实现方法
lm对象的model元素是模型帧,第一列为响应变量,后续每一列对应一个预测变量,因此ncol(x$model) > 2即对应预测变量数量大于1。直接按逻辑条件筛选列表元素即可,不会修改原模型对象、不会丢失属性。
base R 版本
filter_models <- list_models[sapply(list_models, function(x) ncol(x$model) > 2)]
purrr(tidyverse)版本
用keep()函数直接保留符合条件的列表元素:
library(purrr) filter_models <- keep(list_models, ~ncol(.x$model) > 2)
运行上述代码得到的结果和期望输出完全一致,保留了完整的模型信息与lm类属性。
内容的提问来源于stack exchange,提问作者Dollar Tune-bill
相关产品推荐
相关产品推荐

