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 nest
ing and unnest
ing 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]>