I have fitted models, and run dredge()
on them. I have created a data frame
that stores variable names used in the model, and the dredge
object themselves (inside a list
). By using rowwise()
, I was hoping to subset the dredge
object using the variable names stored in a specific column, and keep the subset in a new column.
My problem is that I cannot make this rowwise behaviour to work.
I can subset the dredge
object just fine if I don't try to call the strings stored in other columns, see reproducible example.
I've found related questions from 2019, 2018, and 2014 (here, here). On one hand, these questions use subset
inside the dredge
function, rather than subset
on an already generated dredge
object stored inside a data frame. I've tried using the solutions outlined there, with no success, probably also due to lack of experience with parsing, expressions etc.
library(MuMIn)
#> Warning: package 'MuMIn' was built under R version 4.2.3
library(tidyverse)
#> Warning: package 'ggplot2' was built under R version 4.2.2
#> Warning: package 'tibble' was built under R version 4.2.3
#> Warning: package 'tidyr' was built under R version 4.2.3
#> Warning: package 'purrr' was built under R version 4.2.3
#> Warning: package 'dplyr' was built under R version 4.2.3
#> Warning: package 'stringr' was built under R version 4.2.3
data(Cement)
fm <- lm(y ~ X1*X2 + X1*X3 + X4, Cement)
options(na.action = "na.fail")
d <- MuMIn::dredge(fm)
#> Fixed term is "(Intercept)"
d
#> Global model call: lm(formula = y ~ X1 * X2 + X1 * X3 + X4, data = Cement)
#> ---
#> Model selection table
#> (Int) X1 X2 X3 X4 X1:X2 X1:X3 df logLik AICc
#> 4 52.58 1.4680 0.6623 4 -28.156 69.3
#> 12 71.65 1.4520 0.4161 -0.2365 5 -26.933 72.4
#> 8 48.19 1.6960 0.6569 0.25000 5 -26.952 72.5
#> 10 103.10 1.4400 -0.6140 4 -29.817 72.6
#> 14 111.70 1.0520 -0.41000 -0.6428 5 -27.310 73.2
#> 20 53.71 1.2750 0.6358 0.004197 5 -28.072 74.7
#> 15 203.60 -0.9234 -1.44800 -1.5570 5 -29.734 78.0
#> 28 72.43 1.2870 0.3959 -0.2343 0.003577 6 -26.860 79.7
#> 24 49.05 1.5580 0.6387 0.24590 0.002914 6 -26.904 79.8
#> 16 62.41 1.5510 0.5102 0.10190 -0.1441 6 -26.918 79.8
#> 40 48.17 1.6690 0.6522 0.25180 0.007277 6 -26.933 79.9
#> 46 112.00 1.0680 -0.41490 -0.6462 -0.005210 6 -27.301 80.6
#> 13 131.30 -1.20000 -0.7246 4 -35.372 83.7
#> 32 66.63 1.3570 0.4556 0.06354 -0.1767 0.003398 7 -26.854 90.1
#> 56 49.02 1.5320 0.6342 0.24770 0.002888 0.007116 7 -26.885 90.2
#> 48 60.19 1.5560 0.5298 0.12600 -0.1218 0.004666 7 -26.911 90.2
#> 7 72.07 0.7313 -1.00800 4 -40.965 94.9
#> 9 117.60 -0.7382 3 -45.872 100.4
#> 3 57.42 0.7891 3 -46.035 100.7
#> 11 94.16 0.3109 -0.4569 4 -45.761 104.5
#> 2 81.48 1.8690 3 -48.206 105.1
#> 64 64.80 1.3650 0.4722 0.08329 -0.1585 0.003335 0.003693 8 -26.850 105.7
#> 6 72.35 2.3120 0.49450 4 -48.005 109.0
#> 38 64.05 0.9528 0.49550 0.311600 5 -45.678 109.9
#> 5 110.20 -1.25600 3 -50.980 110.6
#> 1 95.42 2 -53.168 111.5
#> delta weight
#> 4 0.00 0.539
#> 12 3.13 0.113
#> 8 3.16 0.111
#> 10 3.32 0.102
#> 14 3.88 0.078
#> 20 5.40 0.036
#> 15 8.73 0.007
#> 28 10.41 0.003
#> 24 10.49 0.003
#> 16 10.52 0.003
#> 40 10.55 0.003
#> 46 11.29 0.002
#> 13 14.43 0.000
#> 32 20.80 0.000
#> 56 20.86 0.000
#> 48 20.91 0.000
#> 7 25.62 0.000
#> 9 31.10 0.000
#> 3 31.42 0.000
#> 11 35.21 0.000
#> 2 35.77 0.000
#> 64 36.39 0.000
#> 6 39.70 0.000
#> 38 40.61 0.000
#> 5 41.31 0.000
#> 1 42.22 0.000
#> Models ranked by AICc(x)
data.frame(test = c("X1", "X2")) %>%
rowwise() %>%
mutate(dredge = list(d)) %>%
mutate(subset = list(subset(dredge, delta <= 6)))
#> # A tibble: 2 × 3
#> # Rowwise:
#> test dredge subset
#> <chr> <list> <list>
#> 1 X1 <mdl.slct [26 × 12]> <mdl.slct [6 × 12]>
#> 2 X2 <mdl.slct [26 × 12]> <mdl.slct [6 × 12]>
data.frame(test = c("X1", "X2")) %>%
rowwise() %>%
mutate(dredge = list(d)) %>%
mutate(subset = list(subset(dredge, has("X1"))))
#> # A tibble: 2 × 3
#> # Rowwise:
#> test dredge subset
#> <chr> <list> <list>
#> 1 X1 <mdl.slct [26 × 12]> <mdl.slct [18 × 12]>
#> 2 X2 <mdl.slct [26 × 12]> <mdl.slct [18 × 12]>
data.frame(test = c("X1", "X2")) %>%
rowwise() %>%
mutate(dredge = list(d)) %>%
mutate(subset = list(subset(dredge, has(test))))
#> # A tibble: 2 × 3
#> # Rowwise:
#> test dredge subset
#> <chr> <list> <list>
#> 1 X1 <mdl.slct [26 × 12]> <mdl.slct [26 × 12]>
#> 2 X2 <mdl.slct [26 × 12]> <mdl.slct [26 × 12]>
data.frame(test = c("X1", "X2")) %>%
rowwise() %>%
mutate(dredge = list(d)) %>%
mutate(subset = list(subset(dredge, parse(text = sprintf("has(%s)", test)))))
#> Error in `mutate()`:
#> ℹ In argument: `subset = list(subset(dredge, parse(text =
#> sprintf("has(%s)", test))))`.
#> ℹ In row 1.
#> Caused by error in `xj[i]`:
#> ! invalid subscript type 'expression'
#> Backtrace:
#> ▆
#> 1. ├─... %>% ...
#> 2. ├─dplyr::mutate(...)
#> 3. ├─dplyr:::mutate.data.frame(...)
#> 4. │ └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by)
#> 5. │ ├─base::withCallingHandlers(...)
#> 6. │ └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns)
#> 7. │ └─mask$eval_all_mutate(quo)
#> 8. │ └─dplyr (local) eval()
#> 9. ├─base::subset(dredge, parse(text = sprintf("has(%s)", test)))
#> 10. ├─MuMIn:::subset.model.selection(...)
#> 11. │ └─MuMIn:::`[.model.selection`(...)
#> 12. │ ├─MuMIn:::subset_model_selection(item(x, j, i, ...), origattrib <- attributes(x))
#> 13. │ └─MuMIn:::item(x, j, i, ...)
#> 14. │ └─base::`[.data.frame`(x, i, name, ...)
#> 15. └─base::.handleSimpleError(...)
#> 16. └─dplyr (local) h(simpleError(msg, call))
#> 17. └─rlang::abort(message, class = error_class, parent = parent, call = error_call)
data.frame(test = c("X1", "X2")) %>%
rowwise() %>%
mutate(dredge = list(d)) %>%
mutate(subset = list(subset(dredge, eval(parse(text = sprintf("has(%s)", test))))))
#> Error in `mutate()`:
#> ℹ In argument: `subset = list(subset(dredge, eval(parse(text =
#> sprintf("has(%s)", test)))))`.
#> ℹ In row 1.
#> Caused by error in `has()`:
#> ! no se pudo encontrar la función "has"
#> Backtrace:
#> ▆
#> 1. ├─... %>% ...
#> 2. ├─dplyr::mutate(...)
#> 3. ├─dplyr:::mutate.data.frame(...)
#> 4. │ └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by)
#> 5. │ ├─base::withCallingHandlers(...)
#> 6. │ └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns)
#> 7. │ └─mask$eval_all_mutate(quo)
#> 8. │ └─dplyr (local) eval()
#> 9. ├─base::subset(dredge, eval(parse(text = sprintf("has(%s)", test))))
#> 10. ├─MuMIn:::subset.model.selection(...)
#> 11. │ ├─MuMIn:::`[.model.selection`(...)
#> 12. │ │ ├─MuMIn:::subset_model_selection(item(x, j, i, ...), origattrib <- attributes(x))
#> 13. │ │ └─MuMIn:::item(x, j, i, ...)
#> 14. │ │ └─base::`[.data.frame`(x, i, name, ...)
#> 15. │ └─MuMIn:::subset_eval(substitute(subset), x, parent.frame())
#> 16. │ └─base::eval(...)
#> 17. │ └─base::eval(...)
#> 18. │ └─base::eval(parse(text = sprintf("has(%s)", test)))
#> 19. │ └─base::eval(parse(text = sprintf("has(%s)", test)))
#> 20. └─base::.handleSimpleError(...)
#> 21. └─dplyr (local) h(simpleError(msg, call))
#> 22. └─rlang::abort(message, class = error_class, parent = parent, call = error_call)
data.frame(test = c("X1", "X2")) %>%
rowwise() %>%
mutate(dredge = list(d)) %>%
mutate(subset = list(subset(dredge, has(substitute(v, list(v = as.name("test")))))))
#> Error in `mutate()`:
#> ℹ In argument: `subset = list(subset(dredge, has(substitute(v, list(v =
#> as.name("test"))))))`.
#> ℹ In row 1.
#> Caused by error:
#> ! objeto 'substitute(v, list(v = as.name("test")))' no encontrado
#> Backtrace:
#> ▆
#> 1. ├─... %>% ...
#> 2. ├─dplyr::mutate(...)
#> 3. ├─dplyr:::mutate.data.frame(., subset = list(subset(dredge, has(substitute(v, list(v = as.name("test")))))))
#> 4. │ └─dplyr:::mutate_cols(.data, dplyr_quosures(...), by)
#> 5. │ ├─base::withCallingHandlers(...)
#> 6. │ └─dplyr:::mutate_col(dots[[i]], data, mask, new_columns)
#> 7. │ └─mask$eval_all_mutate(quo)
#> 8. │ └─dplyr (local) eval()
#> 9. ├─base::subset(dredge, has(substitute(v, list(v = as.name("test")))))
#> 10. ├─MuMIn:::subset.model.selection(dredge, has(substitute(v, list(v = as.name("test")))))
#> 11. │ ├─MuMIn:::`[.model.selection`(...)
#> 12. │ │ ├─MuMIn:::subset_model_selection(item(x, j, i, ...), origattrib <- attributes(x))
#> 13. │ │ └─MuMIn:::item(x, j, i, ...)
#> 14. │ │ └─base::`[.data.frame`(x, i, name, ...)
#> 15. │ └─MuMIn:::subset_eval(substitute(subset), x, parent.frame())
#> 16. │ └─base::eval(...)
#> 17. │ └─base::eval(...)
#> 18. └─base::.handleSimpleError(...)
#> 19. └─dplyr (local) h(simpleError(msg, call))
#> 20. └─rlang::abort(message, class = error_class, parent = parent, call = error_call)
sessionInfo()
#> R version 4.2.0 (2022-04-22 ucrt)
#> Platform: x86_64-w64-mingw32/x64 (64-bit)
#> Running under: Windows 10 x64 (build 22000)
#>
#> Matrix products: default
#>
#> locale:
#> [1] LC_COLLATE=Spanish_Spain.utf8 LC_CTYPE=Spanish_Spain.utf8
#> [3] LC_MONETARY=Spanish_Spain.utf8 LC_NUMERIC=C
#> [5] LC_TIME=Spanish_Spain.utf8
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] forcats_0.5.1 stringr_1.5.0 dplyr_1.1.2 purrr_1.0.1
#> [5] readr_2.1.2 tidyr_1.3.0 tibble_3.2.1 ggplot2_3.4.0
#> [9] tidyverse_1.3.1 MuMIn_1.47.5
#>
#> loaded via a namespace (and not attached):
#> [1] tidyselect_1.2.0 xfun_0.40 haven_2.5.0 lattice_0.20-45
#> [5] colorspace_2.0-3 vctrs_0.6.3 generics_0.1.2 htmltools_0.5.6
#> [9] stats4_4.2.0 yaml_2.3.5 utf8_1.2.2 rlang_1.1.1
#> [13] pillar_1.9.0 glue_1.6.2 withr_2.5.0 DBI_1.1.2
#> [17] dbplyr_2.1.1 readxl_1.4.0 modelr_0.1.8 lifecycle_1.0.3
#> [21] cellranger_1.1.0 munsell_0.5.0 gtable_0.3.0 rvest_1.0.2
#> [25] evaluate_0.15 knitr_1.39 tzdb_0.3.0 fastmap_1.1.0
#> [29] fansi_1.0.3 highr_0.9 broom_0.8.0 backports_1.4.1
#> [33] scales_1.2.1 jsonlite_1.8.0 fs_1.5.2 hms_1.1.1
#> [37] digest_0.6.29 stringi_1.7.6 grid_4.2.0 cli_3.6.1
#> [41] tools_4.2.0 magrittr_2.0.3 crayon_1.5.1 pkgconfig_2.0.3
#> [45] ellipsis_0.3.2 Matrix_1.4-1 xml2_1.3.3 lubridate_1.8.0
#> [49] reprex_2.0.2 assertthat_0.2.1 rmarkdown_2.14 httr_1.4.3
#> [53] rstudioapi_0.13 R6_2.5.1 nlme_3.1-157 compiler_4.2.0
Created on 2023-09-29 with reprex v2.0.2
I'm not exactly sure why the subset won't work inside mutate()
the usual way. I was able to get the desired result using map()
inside the mutate()
function. The documentation for subset
for the dredge object says that has("X1")
is equivalent to !is.na(X1)
, so I used the latter instead (has()
still doesn't work in this context).
library(MuMIn)
library(tidyverse)
data(Cement)
fm <- lm(y ~ X1*X2 + X1*X3 + X4, Cement)
options(na.action = "na.fail")
d <- MuMIn::dredge(fm)
#> Fixed term is "(Intercept)"
data.frame(test = c("X1", "X2")) %>%
rowwise() %>%
mutate(dredge = list(d)) %>%
mutate(subset = map(test, \(x)subset(d, !is.na(d[[x]]))))
#> # A tibble: 2 × 3
#> # Rowwise:
#> test dredge subset
#> <chr> <list> <list>
#> 1 X1 <mdl.slct [26 × 12]> <mdl.slct [18 × 12]>
#> 2 X2 <mdl.slct [26 × 12]> <mdl.slct [16 × 12]>
Created on 2023-09-29 with reprex v2.0.2