I have a tibble like:
tibble(a = c('first', 'second'),
b = list(c('colA' = 1, 'colC' = 2), c('colA'= 3, 'colB'=2)))
# A tibble: 2 x 2
a b
<chr> <list>
1 first <dbl [2]>
2 second <dbl [2]>
Which a would like to turn into this form:
# A tibble: 2 x 4
a colA colB colC
<chr> <dbl> <dbl> <dbl>
1 first 1. NA 2.
2 second 3. 2. NA
I tried to use unnest()
, but I am having issues preserving the elements' names from the nested values.
You can do this by coercing the elements in the list column to data frames arranged as you like, which will unnest nicely:
library(tidyverse)
tibble(a = c('first', 'second'),
b = list(c('colA' = 1, 'colC' = 2), c('colA'= 3, 'colB'=2))) %>%
mutate(b = invoke_map(tibble, b)) %>%
unnest()
#> # A tibble: 2 x 4
#> a colA colC colB
#> <chr> <dbl> <dbl> <dbl>
#> 1 first 1. 2. NA
#> 2 second 3. NA 2.
Doing the coercion is a little tricky, though, as you don't want to end up with a 2x1 data frame. There are various ways around this, but a direct route is purrr::invoke_map
, which calls a function with purrr::invoke
(like do.call
) on each element in a list.
With tidyr
1.0.0, we can use unnest_wider
to directly add new columns.
tidyr::unnest_wider(df,b)
# A tibble: 2 x 4
# a colA colC colB
# <chr> <dbl> <dbl> <dbl>
#1 first 1 2 NA
#2 second 3 NA 2
data
df <- tibble(a = c('first', 'second'),
b = list(c('colA' = 1, 'colC' = 2), c('colA'= 3, 'colB'=2)))