Unnest data frame list columns
unnest_cross.RdLike tidyr::unnest() but always produces a cartesian product and does not
requires that list columns be "parallel entries ... of compatible sizes".
Arguments
- data
A data.frame.
- cols
<
tidy-select> Columns to unnest.- ...
Arguments passed on to
tidyr::unchop,tidyr::unpackerror_callThe execution environment of a currently running function, e.g.
caller_env(). The function will be mentioned in error messages as the source of the error. See thecallargument ofabort()for more information.keep_emptyBy default, you get one row of output for each element of the list that you are unchopping/unnesting. This means that if there's a size-0 element (like
NULLor an empty data frame or vector), then that entire row will be dropped from the output. If you want to preserve all rows, usekeep_empty = TRUEto replace size-0 elements with a single row of missing values.ptypeOptionally, a named list of column name-prototype pairs to coerce
colsto, overriding the default that will be guessed from combining the individual values. Alternatively, a single empty ptype can be supplied, which will be applied to allcols.data,.dataA data frame.
names_sep,.names_sepIf
NULL, the default, the names will be left as is. Inpack(), inner names will come from the former outer names; inunpack(), the new outer names will come from the inner names.If a string, the inner and outer names will be used together. In
unpack(), the names of the new outer columns will be formed by pasting together the outer and the inner column names, separated bynames_sep. Inpack(), the new inner names will have the outer names +names_sepautomatically stripped. This makesnames_seproughly symmetric between packing and unpacking.names_repairUsed to check that output data frame has valid names. Must be one of the following options:
"minimal": no name repair or checks, beyond basic existence,"unique": make sure names are unique and not empty,"check_unique": (the default), no name repair, but check they are unique,"universal": make the names unique and syntactica function: apply custom name repair.
tidyr_legacy: use the name repair from tidyr 0.8.
a formula: a purrr-style anonymous function (see
rlang::as_function())
See
vctrs::vec_as_names()for more details on these terms and the strategies used to enforce them.error_call,.error_callThe execution environment of a currently running function, e.g.
caller_env(). The function will be mentioned in error messages as the source of the error. See thecallargument ofabort()for more information.
Examples
df <- tibble::tibble(
n = 1:2,
interjection = list(c("oh", "wow"), "zap"),
letter = list(c("a", "b", "c"), "d"),
keep_list = list("please", c("don't", "unnest"))
)
df
#> # A tibble: 2 × 4
#> n interjection letter keep_list
#> <int> <list> <list> <list>
#> 1 1 <chr [2]> <chr [3]> <chr [1]>
#> 2 2 <chr [1]> <chr [1]> <chr [2]>
# Uses tidyselect semantics, like tidyr::unnest()
unnest_cross(df, cols = tidyselect::starts_with("inter"))
#> # A tibble: 3 × 4
#> n interjection letter keep_list
#> <int> <chr> <list> <list>
#> 1 1 oh <chr [3]> <chr [1]>
#> 2 1 wow <chr [3]> <chr [1]>
#> 3 2 zap <chr [1]> <chr [2]>
# Works when list column sizes differ, unlike tidyr::unnest()
tryCatch(
tidyr::unnest(df, cols = c(interjection, letter)),
error = function(e) message(e)
)
#> Error in tidyr::unnest(df, cols = c(interjection, letter)): In row 1, can't recycle input of size 2 to size 3.
unnest_cross(df, cols = c(interjection, letter))
#> # A tibble: 7 × 4
#> n interjection letter keep_list
#> <int> <chr> <chr> <list>
#> 1 1 oh a <chr [1]>
#> 2 1 oh b <chr [1]>
#> 3 1 oh c <chr [1]>
#> 4 1 wow a <chr [1]>
#> 5 1 wow b <chr [1]>
#> 6 1 wow c <chr [1]>
#> 7 2 zap d <chr [2]>
# Always produces a cartesian product, unlike tidyr::unnest()
df2 <- tibble::tibble(
n = list(1:2, 3L),
letter = list(c("a", "b"), "c"),
)
df2
#> # A tibble: 2 × 2
#> n letter
#> <list> <list>
#> 1 <int [2]> <chr [2]>
#> 2 <int [1]> <chr [1]>
tidyr::unnest(df2, cols = tidyselect::everything())
#> # A tibble: 3 × 2
#> n letter
#> <int> <chr>
#> 1 1 a
#> 2 2 b
#> 3 3 c
unnest_cross(df2, cols = tidyselect::everything())
#> # A tibble: 5 × 2
#> n letter
#> <int> <chr>
#> 1 1 a
#> 2 1 b
#> 3 2 a
#> 4 2 b
#> 5 3 c