1

Consider a list a of vectors. All vectors have the same type (i.e. Date in my case), vectors can have different lenght.

> str(a)
List of 2
 $ item1: Date[1:3], format: "1999-02-06" "1999-10-23" "1999-09-13"
 $ item2: Date[1:2], format: "1999-12-05" "1999-11-30"

How to convert this list in a long-dataframe-like structure? The expected output looks like:

items dates
item1 1999-02-06
item1 1999-10-23
item1 1999-09-13
item2 1999-12-05
item2 1999-11-30

The code to make a:

a <- list(item1 = structure(c(10628, 10887, 10847), class = "Date"), 
    item2 = structure(c(10930, 10925), class = "Date"), item3 = structure(c(10764, 
    10671, 10917, 10887), class = "Date"))

In this case, "usual" technique involving row/col-wise binding do not work:

>   bind_rows(a)
Error:
! Tibble columns must have compatible sizes.
• Size 2: Column `item2`.
• Size 3: Column `item1`.
ℹ Only values of size one are recycled.
>   bind_cols(a)
Error in `bind_cols()`:
! Can't recycle `item1` (size 3) to match `item2` (size 2).

I feel this question has already an answer on SO but I might not have used the correct keywords... Here are some posts I found:

But they do not answer this question as the output is not in long format and require to padding each shorter vector with NA. I could do this and then pivot_longer() but maybe there is a way without filling shorter vectors with NA.

Paul
  • 2,850
  • 1
  • 12
  • 37

1 Answers1

1

Use tibble::enframe with tidyr::unnest:

library(tibble)
library(tidyr)
enframe(a, name = "items", value = "dates") %>%
   unnest(dates)
  items dates     
1 item1 1999-02-06
2 item1 1999-10-23
3 item1 1999-09-13
4 item2 1999-12-05
5 item2 1999-11-30
6 item3 1999-06-22
7 item3 1999-03-21
8 item3 1999-11-22
9 item3 1999-10-23
Paul
  • 2,850
  • 1
  • 12
  • 37
Maël
  • 45,206
  • 3
  • 29
  • 67
  • 1
    Just perfect, thank you! Even after all this time I have never seen this function being used... – Paul Sep 02 '22 at 08:52