Home > Back-end >  Get only linear models with more than one predictor from list
Get only linear models with more than one predictor from list

Time:06-07

I have a list of linear models and want to only grab those with more than one predictor.

Here's my example data:

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)

My approach:

map(list_models, function(x)if(length(names(x$model))>2){
  list_models
})

This approach seems to return far too many models.

Alternatively:

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 

However, these are not saved as linear models (notice the 'Call' is not introduced).

Expected output:

[[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  

CodePudding user response:

I would filter on the presence or absence of a " " in the formula call, e.g.:

lm_1term = lm(data=mtcars,mpg~cyl)
lm_2terms = lm(data=mtcars,mpg~cyl hp)

models = list(lm_1term, lm_2terms)

The formula (as a string) is retrievable via

as.character(lm_2terms$call)[2]

gives us mpg ~ cyl hp, so that we can define a True/False function

single_predictor <- function(model) !grepl(as.character(model$call)[2], 
                                           pattern=' ', fixed=T)

Then you can use Filter to select elements from the list:

Filter(single_predictor, models)

CodePudding user response:

Turns out this one liner get's the job done regardless if a formula is used or not.

list_models %>% keep(~all(length(names(.$model))>2))
  •  Tags:  
  • r
  • Related