Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

export magrittr::extract()? #223

Closed
jennybc opened this issue Aug 13, 2016 · 7 comments
Closed

export magrittr::extract()? #223

jennybc opened this issue Aug 13, 2016 · 7 comments

Comments

@jennybc
Copy link
Member

@jennybc jennybc commented Aug 13, 2016

I taught purrr today. We selected multiple elements at the same level of the list hierarchy. Overall reaction was "elegant and simplifying", but mapping [ was described as "ugly and horrifying".

Is there any chance of re-exporting magrittr::extract()?

library(purrr)
library(magrittr)

x <- list(list(one = list(alpha = 1, beta = 2), two = "three", three = 4),
          list(one = list(alpha = 5, beta = 6), two = "seven", three = 8))
#x %>% map_dbl(c("one", "beta"))
#x %>% map_df(`[`, c("two", "three"))
x %>% map_df(extract, c("two", "three"))
#> # A tibble: 2 x 2
#>     two three
#>   <chr> <dbl>
#> 1 three     4
#> 2 seven     8
@lionel-
Copy link
Member

@lionel- lionel- commented Aug 13, 2016

mapping [ was described as "ugly and horrifying"

:) That may just be because they are not used to it. Once you get the hang of mapping operators you can do stuff like this: x %>% some(==, "") which is kind of elegant I would say.

extract() is already quite overloaded across packages. Maybe vct_subset() and vct_extract() for [and [[ respectively? I like the vct_ prefix (or maybe vec_) but it requires knowing that both lists and atomic vectors are vectors and it's not how R neophytes usually think about it.

@jennybc
Copy link
Member Author

@jennybc jennybc commented Aug 13, 2016

That may just be because they are not used to it

That's true. My own horror at this has now faded to a distant memory.

I think it catches attention because many people don't predict that using a vector as .f will index at successively deeper levels of the input, e.g. map_dbl(c("one", "beta")) in the example. That's not very well-known. So it's easy to be surprised about which syntax does what. And to be disappointed about which one requires a bit more work.

retrieve()?

Also in a past email conversation, there was talk of a select method for lists. Reminding you of a relevant example you wrote:

library(purrr)
library(dplyr)
x <- rerun(2, head(mtcars,2))
x %>% map_df(select, cyl, am)
#>   cyl am
#> 1   6  1
#> 2   6  1
#> 3   6  1
#> 4   6  1

@hadley
Copy link
Member

@hadley hadley commented Sep 21, 2016

I'd rather fix this by improving the documentation for map() so that you know you can use a character vector to index deeply into an object.

@hadley hadley closed this as completed Sep 21, 2016
@jennybc
Copy link
Member Author

@jennybc jennybc commented Sep 21, 2016

I never really thought this would fly but just want to point out this issue was about retrieving "multiple elements at the same level of the list hierarchy". So, more like dplyr::select() but for lists. It was explicitly NOT about using "a character vector to index deeply into an object", which is already well documented.

@hadley
Copy link
Member

@hadley hadley commented Sep 21, 2016

Oh gotcha. I think an explicit [ is probably still the best way to do that even if it makes your students retch in horror.

@dmi3kno
Copy link

@dmi3kno dmi3kno commented Apr 24, 2018

The issue with explicit [, as indicated here and here is that it does not have crucial .default/.null handling. I would insist that the issue is still open and there's a need for multi-value pluck for "tidying" lists.

> purrr::map_dfr(x, ~list(two = purrr::pluck(.x, "two", .default = NA), 
                         three = purrr::pluck(.x, "three", .default = NA)))
#> or

> purrr::map_dfr(x, function(i) purrr::map(purrr::set_names(c("two", "three")), 
                                          ~purrr::pluck(i, .x, .default = NA)))

#>  A tibble: 2 x 2
#>  two   three
#>  <chr> <dbl>
#>1 three  4.00
#>2 seven  8.00

Or, what I usually need for creating list-columns:

> purrr::map(x, ~tibble::tibble(two=purrr::pluck(.x, "two", .default = NA), 
                      three=purrr::pluck(.x, "three", .default = NA)))
#> or

> purrr::map(x, function(i) purrr::map_dfr(purrr::set_names(c("two", "three")), 
                                        ~purrr::pluck(i, .x, .default = NA)))

#> [[1]]
#> # A tibble: 1 x 2
#>   two   three
#>   <chr> <dbl>
#> 1 three  4.00
#> 
#> [[2]]
#> # A tibble: 1 x 2
#>   two   three
#>   <chr> <dbl>
#> 1 seven  8.00

@batpigandme
Copy link
Member

@batpigandme batpigandme commented Apr 24, 2018

@dmi3kno since this issue was closed over a year ago, commenting here is pretty low-visibility. If you could please open a new issue that refers back to this with your reprex etc., it will be much easier for the maintainers to find it.

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants