Reputation: 325
How can I find the element in a list column based on the value in another column using purrr?
For instance, imagine I have a simple tibble with 2 columns and 2 rows. The second column is a list column with both rows showing the "letters" vector as a list. The first column shows the element of the list that I would like to extract.
library(dplyr)
library(purrr)
lets <- tibble(posn = 1:2,
lets_list = list(letters, letters)) %>%
glimpse()
returns:
Observations: 2
Variables: 2
$ posn <int> 1, 2
$ lets_list <list> [<"a", "b", "c", "d", "e", "f
Using the purrr package, I can execute the following command:
lets %>%
mutate(lets_sel = map_chr(lets_list, 2))
which returns a new column, "lets_sel" with a value of "b" as this is the second element of the letters vector:
# A tibble: 2 x 3
posn lets_list lets_sel
<int> <list> <chr>
1 1 <chr [26]> b
2 2 <chr [26]> b
However, I would like to use the value in the posn column to specify which element of the lets_list list to return.
I've tried this command without success.
lets %>%
mutate(lets_sel = map_chr(lets_list, posn))
> lets %>%
+ mutate(lets_sel = map_chr(lets_list, posn))
Error in mutate_impl(.data, dots) :
Evaluation error: Result 1 is not a length 1 atomic vector.
As well as numerous variations, such as:
lets %>%
mutate(lets_sel = lets_list[[posn]])
but this returns this incorrect result with "b" and "b" instead of "a" and "b":
# A tibble: 2 x 3
posn lets_list lets_sel
<int> <list> <chr>
1 1 <chr [26]> b
2 2 <chr [26]> b
Upvotes: 2
Views: 885
Reputation: 79208
You would have to use map2_chr
since this takes two arguments
lets %>%
mutate(lets_sel = map2_chr(lets_list, posn,~.x[.y]))
A tibble: 2 x 3
posn lets_list lets_sel
<int> <list> <chr>
1 1 <chr [26]> a
2 2 <chr [26]> b
Upvotes: 1