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 usingmap()inside themutate()function. The documentation forsubsetfor the dredge object says thathas("X1")is equivalent to!is.na(X1), so I used the latter instead (has()still doesn't work in this context).Created on 2023-09-29 with reprex v2.0.2