将tidyr中的一列列表展开为多个列

6
例如,我有一个整洁的数据框,如下所示:
df <- tibble(id=1:2,
         ctn=list(list(a="x",b=1),
                  list(a="y",b=2)))
# A tibble: 2 x 2
     id        ctn
  <int>     <list>
1     1 <list [2]>
2     2 <list [2]>

我应该如何将ctn列拆分成右侧,以使数据框的形式如下:

# A tibble: 2 x 3
     id     a     b
  <int> <chr> <dbl>
1     1     x     1
2     2     y     2
3个回答

13

使用dplyrpurrr

df %>% 
  mutate(ctn = map(ctn, as_tibble)) %>%
  unnest()
# A tibble: 2 x 3
     id     a     b
  <int> <chr> <dbl>
1     1     x     1
2     2     y     2

1
如果你想避免警告(否则你可能想将其包含为输出),请使用as_tibble而不是as.data.frame。或者添加stringsAsFactors=FALSE - talat
@docendodiscimus 谢谢,我已经进行了编辑。完全忘记了stringsAsFactors=FALSE,在启动时通过options()进行更改。 - Andrey Kolyadin
注意:这个方法适用于列表列中的列表,但不适用于列表列中的向量。请参考https://dev59.com/l6rka4cB1Zd3GeqPhrO1以获取列表列中的列表解决方案。 - Arthur Yip

2

其中一个选项是

library(data.table)
setDT(df)[, unlist(ctn, recursive = FALSE), id]
#   id a b
#1:  1 x 1
#2:  2 y 2

或者使用 tidyr
library(tidyverse)
df$ctn %>%
     setNames(., df$id) %>%
     bind_rows(., .id = 'id')
# A tibble: 2 x 3
#   id     a     b
#  <chr> <chr> <dbl>
#1     1     x     1
#2     2     y     2

0
现在我们可以以整洁的方式(使用dplyr 1.0.2及以上版本)使用rowwise()来完成此操作:
df %>% rowwise() %>% mutate(as_tibble(ctn))

# A tibble: 2 x 4
# Rowwise: 
     id ctn              a         b
  <int> <list>           <chr> <dbl>
1     1 <named list [2]> x         1
2     2 <named list [2]> y         2

并且坚持使用purrr,我们还可以:

df %>% mutate(map_dfr(ctn, as_tibble))

# A tibble: 2 x 4
     id ctn              a         b
  <int> <list>           <chr> <dbl>
1     1 <named list [2]> x         1
2     2 <named list [2]> y         2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接