AEM
AEM

Reputation: 948

Use purrr::map to merge list within a tibble with a data frame

I am using purrr and want to use map or on a list list1 within a tibble my_tibble in combination with an external dataframe my_dataframe, the idea is for my_dataframe to be merged to every item of list1:

library(dplyr)
library(purrr)

df1 <- tibble(X = 1:3, A = c("a", "b", "c"))
df2 <- tibble(X = 1:3, A = c("d", "e", "f"))
df3 <- tibble(X = 1:3, A = c("x", "y", "z"))

my_tibble <- tibble (list1 = list(df1, df2, df3), list2 = list(df1, df2, df3)) 


my_dataframe <- tibble(D = 1:9, A = c("d", "e", "f","a", "b", "c","x", "y", "z"))

my_tibble <- my_tibble %>% mutate (list1 = map (list1, function (.x) {
  .x %>% left_join(my_dataframe) } ))

Upvotes: 1

Views: 695

Answers (2)

Anoushiravan R
Anoushiravan R

Reputation: 21938

This can also be done without purrr package function, as it looked pretty straightforward to me and thought you might be interested:

library(dplyr)
library(tidyr)


my_tibble %>%
  mutate(id = row_number()) %>%
  unnest(list1) %>%
  left_join(my_dataframe, by = "A") %>%
  group_by(id) %>%
  nest(data = c(X, A, D)) %>%
  rename(list1 = data) %>%
  ungroup() %>%
  select(-id) %>%
  relocate(list1)


# A tibble: 3 x 2
  list1            list2           
  <list>           <list>          
1 <tibble [3 x 3]> <tibble [3 x 2]>
2 <tibble [3 x 3]> <tibble [3 x 2]>
3 <tibble [3 x 3]> <tibble [3 x 2]>

Upvotes: 2

AnilGoyal
AnilGoyal

Reputation: 26238

Actually you need to mutate every column of my_tibble (if I understand you correct as left_join with my_dataframe. So you have to use mutate(across... along with map as -

my_tibble %>%
  mutate(across(everything(), ~map(., function(.x) .x %>% left_join(my_dataframe, by = c('X' = 'D')))))

# A tibble: 3 x 2
  list1                list2               
  <list>               <list>              
1 <tibble[,3] [3 x 3]> <tibble[,3] [3 x 3]>
2 <tibble[,3] [3 x 3]> <tibble[,3] [3 x 3]>
3 <tibble[,3] [3 x 3]> <tibble[,3] [3 x 3]>

Check

my_tibble %>%
  mutate(across(everything(), ~map(., function(.x) .x %>% left_join(my_dataframe, by = c('X' = 'D'))))) -> result

result$list1[[1]]

# A tibble: 3 x 3
      X A         D
  <int> <chr> <int>
1     1 a         4
2     2 b         5
3     3 c         6

This will work as lambda function too

my_tibble %>%
  mutate(across(everything(), ~map(., ~.x %>% left_join(my_dataframe, by = c('X' = 'D')))))

Upvotes: 2

Related Questions