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