[英]How to unnest multiple list columns of a dataframe in one go with dplyr pipe
我有以下小標題,它有兩個嵌套列:
library(tidyverse)
df <- structure(list(a = list(c("a", "b"), "c"), b = list(c("1", "2",
"3"), "3"), c = c(11, 22)), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -2L))
產生:
# A tibble: 2 x 3
a b c
<list> <list> <dbl>
1 <chr [2]> <chr [3]> 11
2 <chr [1]> <chr [1]> 22
我怎樣才能一次將它們解開,產生一個小標題?
我試過這個但失敗了:
> df %>% unnest(a, b)
Error: All nested columns must have the same number of elements.
可能有一種更清潔的方法,但如果你想要列的笛卡爾積,你可以按順序取消它們,如果沒有別的:
> df %>%
unnest(a, .drop = FALSE) %>%
unnest(b, .drop = FALSE)
# # A tibble: 7 x 3
# c a b
# <dbl> <chr> <chr>
# 1 11 a 1
# 2 11 a 2
# 3 11 a 3
# 4 11 b 1
# 5 11 b 2
# 6 11 b 3
# 7 22 c 3
使用unnest_cross()
(如果 list-cols 缺少數據,請小心 --> keep_empty = TRUE
):
unnest_cross <- function(data, cols, ...) {
.df_out <- data
.cols <- tidyselect::eval_select(rlang::enquo(cols), data)
purrr::walk(
.cols,
function(col) {
.df_out <<- unnest(.df_out, {{ col }}, ...)
}
)
.df_out
}
unnest()
的多個列表列自v0.3.0
(2015) 以來, unnest
已經處理了多個列。 它目前使用cols
參數,該參數接受典型的 tidyverse 選擇方法。
請注意,它專門設計用於反轉nest()
ed data.frames 並要求列表列是“並行條目......大小兼容”。 這表示:
df <- structure(list(
a = list(c("a", "b"), "c"),
b = list(c("1", "2", "3"), "3"),
c = c(11, 22)),
class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -2L))
tidyr::unnest(df, cols = tidyselect::everything())
#> Error in `fn()`:
#> ! In row 1, can't recycle input of size 2 to size 3.
unnest()
相同的輸出(例如笛卡爾積)。# "parallel"/"compatible" data.frame
df_parallel <- structure(list(
a = list(c("a", "b", "c"), "c"),
b = list(c("1", "2", "3"), "3"),
c = c(11, 22)),
class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -2L))
tidyr::unnest(df_parallel, cols = tidyselect::everything())
#> # A tibble: 4 × 3
#> a b c
#> <chr> <chr> <dbl>
#> 1 a 1 11
#> 2 b 2 11
#> 3 c 3 11
#> 4 c 3 22
unnest_cross()
詳細信息 unnest_cross()
使用purrr::walk()
循環遍歷指定的列並unnest()
它們,每次通過超級賦值(使用<<-
)保存結果。 它的名字來源於與purrr::cross()
的相似性,因為它總是產生 data.frame 中列表列的笛卡爾積,即使它們是“並行條目”和/或“大小兼容”
# For original data.frame
unnest_cross(df, cols = tidyselect::everything())
#> # A tibble: 7 × 3
#> a b c
#> <chr> <chr> <dbl>
#> 1 a 1 11
#> 2 a 2 11
#> 3 a 3 11
#> 4 b 1 11
#> 5 b 2 11
#> 6 b 3 11
#> 7 c 3 22
df_parallel
的笛卡爾積,這與unnest()
非常不同。# For df with list-columns of "compatible size"
unnest_cross(df_parallel, cols = tidyselect::everything())
#> # A tibble: 10 × 3
#> a b c
#> <chr> <chr> <dbl>
#> 1 a 1 11
#> 2 a 2 11
#> 3 a 3 11
#> 4 b 1 11
#> 5 b 2 11
#> 6 b 3 11
#> 7 c 1 11
#> 8 c 2 11
#> 9 c 3 11
#> 10 c 3 22
由reprex 包於 2022-06-03 創建 (v2.0.1)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.