How can you use the *frame functions from the package tibble?

dplyr
constructive
tibble
enframe
deframe
nested
Author
Affiliations

Layal Christine Lettry

cynkra GmbH

University of Fribourg, Dept. of Informatics, ASAM Group

Published

August 28, 2024

In which case can you use enframe and deframe?

Initial object

Let’s assume that we have a numeric vector and a list.

my_vec <- c("first" = 1L, "second" = 2L, "third" = 3L)
constructive::construct(my_vec)
c(first = 1L, second = 2L, third = 3L)
my_list <- list(my_vec = my_vec)
constructive::construct(my_list)
list(my_vec = c(first = 1L, second = 2L, third = 3L))

Use enframe() from tibble

Let’s say we need to convert our vector and our list to tibbles. We can use the function enframe() from the tibble package to achieve this.

my_tib_vec <- tibble::enframe(my_vec)
constructive::construct(my_tib_vec)
tibble::tibble(name = c("first", "second", "third"), value = 1:3)
my_tib_list <- tibble::enframe(my_list)
constructive::construct(my_tib_list)
tibble::tibble(name = "my_vec", value = list(c(first = 1L, second = 2L, third = 3L)))

We can see that my_tib_vec and my_tib_list are not the same.

waldo::compare(my_tib_vec, my_tib_list)
`attr(old, 'row.names')`: 1 2 3
`attr(new, 'row.names')`: 1    

`old$name`: "first"  "second" "third"
`new$name`: "my_vec"                 

`old$value` is an integer vector (1, 2, 3)
`new$value` is a list

This difference comes from the fact that the enframe() function converts a named vector into a regular tibble, while a list will be transformed into a nested1 tibble.

To obtain the same tibbles, we need to perform operations on the nested tibble. First, we need to unlist the value variable and to enframe it in a list to retrieve the name of each element. Eventually, we can unnest the column value.

Note that we remove the initial name column which contained the name of the list, namely my_vec, to only keep the name variable corresponding to the names of the list values, i.e. "first", "second" and "third".

my_unnested_tib_list <-
  my_tib_list |>
  dplyr::mutate(value = list(tibble::enframe(unlist(my_tib_list$value)))) |>
  dplyr::select(-name) |>
  tidyr::unnest(cols = value)

constructive::construct(my_unnested_tib_list)
tibble::tibble(name = c("first", "second", "third"), value = 1:3)
waldo::compare(my_tib_vec, my_unnested_tib_list)
✔ No differences

Use deframe() from tibble

To recover our original vector and list, we can use deframe() from tibble.

my_original_vec <- tibble::deframe(my_tib_vec)
constructive::construct(my_original_vec)
c(first = 1L, second = 2L, third = 3L)
waldo::compare(my_vec, my_original_vec)
✔ No differences
my_original_list <- tibble::deframe(my_tib_list)
constructive::construct(my_original_list)
list(my_vec = c(first = 1L, second = 2L, third = 3L))
waldo::compare(my_list, my_original_list)
✔ No differences

Note that the nested tibble is automatically converted to a list thanks to deframe().

Footnotes

  1. You can refer to my former blog posts What is the difference between (un)packing and (un)nesting a tibble? and What are the use cases for using nested data over packed data?.↩︎

Citation

BibTeX citation:
@online{lettry2024,
  author = {Lettry, Layal Christine},
  title = {How Can You Use the *Frame Functions from the Package
    Tibble?},
  date = {2024-08-28},
  url = {https://rdiscovery.netlify.app/posts/2024-08-28_frame-functions/},
  langid = {en}
}
For attribution, please cite this work as:
Lettry, Layal Christine. 2024. “How Can You Use the *Frame Functions from the Package Tibble?” August 28, 2024. https://rdiscovery.netlify.app/posts/2024-08-28_frame-functions/.