How to mutate a new tibble column to include a data frame whose name is given as a string in the tibble?

As part of a wrangling pipeline that involved some nesting and unnesting with {tidyr}, I've got an object that looks like that:

library(dplyr)

trb <-
  tibble(data_mtcars      = rep(list(mtcars), 3),
         data_iris        = rep(list(iris), 3),
         data_trees       = rep(list(trees), 3),
         person           = c("lucy", "dan", "john"),
         chosen_data_name = c("data_mtcars", "data_iris", "data_trees"))

trb
#> # A tibble: 3 x 5
#>   data_mtcars    data_iris      data_trees    person chosen_data_name
#>   <list>         <list>         <list>        <chr>  <chr>           
#> 1 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> lucy   data_mtcars     
#> 2 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> dan    data_iris       
#> 3 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> john   data_trees

And I want to mutate a new column that will include the dataset from either columns 1:3 whose name is given in chosen_data_name column.

In other words, I want to utilize the functionality of get() to replace string with the object that has the same name. But unlike normal call to get(), the object the string refers to is stored inside the tibble and not in the global environment (purposely).

Which is why

trb %>% 
  mutate(chosen_data_here = get(chosen_data_name))

doesn't work.

How can I mutate a new column in trb to get the output:

## # A tibble: 3 x 6
##   data_mtcars    data_iris      data_trees    person chosen_data_name chosen_data_here
##   <list>         <list>         <list>        <chr>  <chr>            <list>          
## 1 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> lucy   data_mtcars      <df [32 x 11]> # mtcars 
## 2 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> dan    data_iris        <df [150 x 5]> # iris 
## 3 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> john   data_trees       <df [31 x 3]>  # trees

Solution 1:

Using nest and rowwise:

trb %>% 
  rowwise() %>% 
  mutate(nest(get(chosen_data_name), chosen_data_here = everything()))

# A tibble: 3 x 6
# Rowwise: 
  data_mtcars    data_iris      data_trees    person chosen_data_name chosen_data_here  
  <list>         <list>         <list>        <chr>  <chr>            <list>            
1 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> lucy   data_mtcars      <tibble [32 x 11]>
2 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> dan    data_iris        <tibble [150 x 5]>
3 <df [32 x 11]> <df [150 x 5]> <df [31 x 3]> john   data_trees       <tibble [31 x 3]> 

Solution 2:

Not sure this is as "automatic" as you might want, but this works:

trb %>% 
  mutate(chosen_data_here = case_when(
    chosen_data_name == "data_mtcars" ~ data_mtcars,
    chosen_data_name == "data_iris" ~ data_iris,
    chosen_data_name == "data_trees" ~ data_trees
  ))
# A tibble: 3 × 6
#   data_mtcars    data_iris      data_trees    person chosen_data_name chosen_data_here
#   <list>         <list>         <list>        <chr>  <chr>            <list>          
# 1 <df [32 × 11]> <df [150 × 6]> <df [31 × 3]> lucy   data_mtcars      <df [32 × 11]>  
# 2 <df [32 × 11]> <df [150 × 6]> <df [31 × 3]> dan    data_iris        <df [150 × 6]>  
# 3 <df [32 × 11]> <df [150 × 6]> <df [31 × 3]> john   data_trees       <df [31 × 3]>