0

This is related to the questions 1 and 2

I have a list of objects (in my case they are also lists AFAII), as returned by running:

gof_stats <- models %>% map(gof_stats)

Where models is a list of models created by fitdistrplus and gof_stats is a function that computes goodness of fit stats for each model.

Now if I want to extract a specific stat from that list I could do something like:

gof_stats[[1]]$cvm

to get the Cramer von Mises stat. I can achieve the same over the whole list (as per the linked questions) like so:

cvms <- sapply(gof_stats, "[[", "cvm")

Is there a way to do the same using dplyr/purrr syntax?

BONUS: How would you handle the case where some of the elements in the models list are NULL?

Community
  • 1
  • 1
Bar
  • 2,736
  • 3
  • 33
  • 41

2 Answers2

6

If you prefer map to sapply for this, you can do

library(purrr)
map(gof_stats, ~ .x[["cvm"]])

If you just like pipes you could do

gof_stats %>% sapply("[[", "cvm")

Your question is about lists, not data frames, so dplyr doesn't really apply. You may want to look up ?magrittr::multiply_by to see a list of other aliases from the package that defines %>% as you seem to like piping. For example, magrittr::extract2 is an alias of [[ that can be easily used in the middle of a piping chain.

As for your bonus, I would pre-filter the list to remove NULL elements before attempting to extract things.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Could you explain what the tilde `~` does in the map solution? – Bar Jul 08 '16 at 23:55
  • 1
    See `?map`, under *Arguments*, `.f`, *If a formula, e.g. `~ .x + 2`...*. It's also used in the examples. If you want more detail, have a look at the [vignette of the `lazyeval` package](https://cran.r-project.org/web/packages/lazyeval/vignettes/lazyeval.html). Essentially the `~` is used to coerce the expression that follows to be a formula. – Gregor Thomas Jul 09 '16 at 00:03
  • Or just "cvm" because string inputs are used as indexes – hadley Jul 09 '16 at 03:45
0

A solution composed completely of tidyverse functions is:

gof_stats %>%
   map(~ .x %>% pluck("cvm"))

Legend:

  • map is the tidyverse function for lists, replacing the apply family
  • .x is the object in each iteration
  • ~ is the purrr short syntax for the anonymous function function(x) { }
  • pluck extracts a list element by index or string
Agile Bean
  • 6,437
  • 1
  • 45
  • 53