当第一个索引表示行时,如何处理列表列表?

时间:2018-02-01 17:47:40

标签: r list tibble

如何将列表列表转换为DataFrame,其中第一个"层"列表应该是行?

myList = list(
    list(name="name1",num=20,dogs=list("dog1")),
    list(name="name2",num=13,dogs = list()),
    list(name="name3",num=5,dogs=list("dog2","dog4"))
)

我的第一个想法是取消第三层"

中的元素
myUnList = sapply(myList,function(x){y=x;y$dogs = unlist(y$dogs);y})

我可以创建一个tibble

tibble(myUnList)
# A tibble: 3 x 1
    myUnList
      <list>
1 <list [3]>
2 <list [2]>
3 <list [3]>

请注意,如果我myList[[1]]代表name的向量,那么这很简单,但我在如何整理其他方式提供的数据方面遇到了麻烦。我虽然使用purrr来&#34;反转&#34;订单。

预期结果:

# A tibble: 3 x 3
      names       num       dogs
     <list>    <list>     <list>
1 <chr [1]> <dbl [1]> <list [1]>
2 <chr [1]> <dbl [1]> <list [0]>
3 <chr [1]> <dbl [1]> <list [2]>

是否有其他类型的数据结构支持不同长度的条目?

2 个答案:

答案 0 :(得分:1)

We can extract the list element by using map function from the purrr package and then create a new tibble using data_frame.

library(tidyverse)

dat <- data_frame(name = map_chr(myList, "name"),
                  num = map_dbl(myList, "num"),
                  dogs = map(myList, "dogs"))
dat
# # A tibble: 3 x 3
#    name    num dogs      
#   <chr> <dbl> <list>    
# 1 name1 20.0  <list [1]>
# 2 name2 13.0  <NULL>    
# 3 name3  5.00 <list [2]>

And if you prefer everything to be in list column, replace map_chr and map_dbl with map.

dat <- data_frame(name = map(myList, "name"),
                  num = map(myList, "num"),
                  dogs = map(myList, "dogs"))
dat
#   name      num       dogs      
#   <list>    <list>    <list>    
# 1 <chr [1]> <dbl [1]> <list [1]>
# 2 <chr [1]> <dbl [1]> <NULL>    
# 3 <chr [1]> <dbl [1]> <list [2]>

答案 1 :(得分:1)

在玩purrr一段时间之后,我得到了另一个不需要输入名字的解决方案(对于非常大的列表来说可能很麻烦)。

myList %>% transpose %>% simplify_all %>% tbl_df

结果

# A tibble: 3 x 3
   name   num       dogs
  <chr> <dbl>     <list>
1 name1    20 <list [1]>
2 name2    13 <list [0]>
3 name3     5 <list [2]>

来自transpose的{​​{1}}功能会自动进行此类转换。