考虑这个简单的例子
mydf <- data_frame(regular_col = c(1,2),
normal_col = c('a','b'),
weird_col = list(list('hakuna', 'matata'),
list('squash', 'banana')))
> mydf
# A tibble: 2 x 3
regular_col normal_col weird_col
<dbl> <chr> <list>
1 1 a <list [2]>
2 2 b <list [2]>
我想提取 weird_col
的元素(以编程方式,元素数量可能会改变),以便每个元素放置在不同的列上。也就是说,我期望以下输出
> data_frame(regular_col = c(1,2),
+ normal_col = c('a','b'),
+ weirdo_one = c('hakuna', 'squash'),
+ weirdo_two = c('matata', 'banana'))
# A tibble: 2 x 4
regular_col normal_col weirdo_one weirdo_two
<dbl> <chr> <chr> <chr>
1 1 a hakuna matata
2 2 b squash banana
但是,我无法简单地做到这一点。例如,使用经典的 unnest 在这里会失败,因为它扩展了数据框,而不是将列表的每个元素放置在不同的列中。
> mydf %>% unnest(weird_col)
# A tibble: 4 x 3
regular_col normal_col weird_col
<dbl> <chr> <list>
1 1 a <chr [1]>
2 1 a <chr [1]>
3 2 b <chr [1]>
4 2 b <chr [1]>
tidyverse 中有没有解决方案?
最佳答案
您可以从 unnest
的输出中提取值,进行一些处理以创建列名称,然后展开
返回。请注意,我使用 flatten_chr
因为您的深度为一列表列,但如果它是嵌套的,您可以使用 flatten
和 spread
的工作原理如下在列表列上很好。
library(tidyverse)
#> Warning: package 'dplyr' was built under R version 3.5.1
mydf <- data_frame(
regular_col = c(1, 2),
normal_col = c("a", "b"),
weird_col = list(
list("hakuna", "matata"),
list("squash", "banana")
)
)
mydf %>%
unnest(weird_col) %>%
group_by(regular_col, normal_col) %>%
mutate(
weird_col = flatten_chr(weird_col),
weird_colname = str_c("weirdo_", row_number())
) %>% # or just as.character
spread(weird_colname, weird_col)
#> # A tibble: 2 x 4
#> # Groups: regular_col, normal_col [2]
#> regular_col normal_col weirdo_1 weirdo_2
#> <dbl> <chr> <chr> <chr>
#> 1 1 a hakuna matata
#> 2 2 b squash banana
由reprex package于2018年8月12日创建(v0.2.0)。
关于r - 如何 "spread"列表列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51813445/