James N
James N

Reputation: 325

How to extract the element in a list column based on the value in another column using purrr

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

Answers (1)

Onyambu
Onyambu

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

Related Questions