Unnest a list column directly into several columns

With data.table it's pretty simple:

library("data.table")
setDT(df1)
df1[, c("V1", "V2") := transpose(values)]
df1
#    gr values V1 V2
# 1:  a    1,2  1  2
# 2:  b    3,4  3  4
# 3:  c    5,6  5  6

library(tibble)

df1 <- data_frame(
  gr = c('a', 'b', 'c'),
  values = list(1:2, 3:4, 5:6)
)

library(tidyverse)

df1 %>%
  mutate(r = map(values, ~ data.frame(t(.)))) %>%
  unnest(r) %>%
  select(-values)

# # A tibble: 3 x 3
#   gr       X1    X2
#   <chr> <int> <int>
# 1 a         1     2
# 2 b         3     4
# 3 c         5     6

Maybe this:

cbind(df1[, "gr"], do.call(rbind, df1$values))

with tidyr 1.0.0 you can do :

library(tidyr)
df1 <- tibble(
  gr = c('a', 'b', 'c'),
  values = list(1:2, 3:4, 5:6)
)

unnest_wider(df1, values)
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> New names:
#> * `` -> ...1
#> * `` -> ...2
#> # A tibble: 3 x 3
#>   gr     ...1  ...2
#>   <chr> <int> <int>
#> 1 a         1     2
#> 2 b         3     4
#> 3 c         5     6

Created on 2019-09-14 by the reprex package (v0.3.0)

The output is verbose here because the elements that were unnested horizontally (the vector elements) were not named, and unnest_wider doesn't want to guess silently.

We can name them beforehand to avoid it :

df1 %>%
  dplyr::mutate(values = purrr::map(values, setNames, c("V1","V2"))) %>%
  unnest_wider(values)
#> # A tibble: 3 x 3
#>   gr       V1    V2
#>   <chr> <int> <int>
#> 1 a         1     2
#> 2 b         3     4
#> 3 c         5     6

Or just use suppressMessages() or purrr::quietly()

Tags:

R

Tidyr

Tibble