6

I have the following nasty, nested list

Edit: updated to include value_I_dont_want

mylist <- list(
  list(
    nested_1 = list(
      nested_2 = list(
        list( value_I_want = "a", value_I_dont_want = "f"),
        list( value_I_want = "b", value_I_dont_want = "g")
      )
    )
  ),
  list(
    nested_1 = list(
      nested_2 = list(
        list( value_I_want = "c", value_I_dont_want = "h"),
        list( value_I_want = "d", value_I_dont_want = "i"),
        list( value_I_want = "e", value_I_dont_want = "j")
      )
    )
  )
)

And I want to get all the value_I_wants

I know I can use the following code within a for loop

mylist[[x]]$nested_1$nested_2[[y]]$value_I_want

But I want to improve my map skills. I understand how to use map_chr when the list is a single level but I haven't found many resources on plucking from very nested lists. I also know I can use [[ but haven't found good documentation for when this is appropriate?

Any help appreciated!

MayaGans
  • 1,815
  • 9
  • 30

2 Answers2

4

If we need the 'yay's

library(purrr)
library(dplyr)
map(mylist, ~ .x$nested_1$nested_2 %>% unlist%>% grep("^yay", ., value = TRUE))

Or use pluck to extract the elements based on the key 'value_I_want' after looping over the list with map

map(mylist, ~ .x$nested_1$nested_2 %>% 
                     map(pluck, "value_I_want") )
akrun
  • 874,273
  • 37
  • 540
  • 662
  • Ah ha! Thank you! This is super helpful but what I didn't include in my minimal example is that there are other elements in the unnamed list `list( value_I_want = "yay_1", value_I_dont_want = "no"),` so I cant just use unlist. I will update my question to reflect that – MayaGans Mar 29 '20 at 17:41
  • Thank you again for your help - I'd like to avoid using grep because in my real data the values are actually quite different. Thanks for helping me to pinpoint my issue - so sorry for the confusion! – MayaGans Mar 29 '20 at 17:49
  • 1
    @MayaGans with `pluck` we are only getting those elements that have the key 'value_I_want' – akrun Mar 29 '20 at 17:50
2

A more general solution that requires we only know how deeply the desired values are nested:

map(mylist, ~pluck(.,1,1) %>% map(pluck, "value_I_want")) 

The second pluck operates on the nesting level set by the first pluck.

This can also work on nested lists that are missing intermediate names, as often found in JSON data pulled from the internet.

GGAnderson
  • 1,993
  • 1
  • 14
  • 25