如何将r数据帧的多个列组合成一个列表的单个列

时间:2018-02-17 01:22:13

标签: r list dataframe nested-lists

我想将数据框中的多个列合并到该数据框中作为列表的一列中。例如,我有以下数据框架成分:

name1 name2 imgID attr1 attr2 attr3...
Item1 ItemID1 Img1 water chocolate soy...
Item2 ItemID2 Img2 cocoa spice milk...

我想将attr列组合成一个列,这些列是这些项的逗号分隔列表,如果可能,它们将以下列格式显示:

name1 name2 imgID attrs
Item1 ItemID1 Img1 c("water", "chocolate", "soy", ...)
Item2 ItemID2 Img2 c("cocoa", "spice", "milk", ...)

使用粘贴或连接编写代码是否有简洁的方法允许我将数据框的列调用为ingredients[4:50]而不是按名称调用每个?还有一种方法可以不在该列表中包含NANULL值吗?

1 个答案:

答案 0 :(得分:1)

您可以使用tidyr::nest,但您可能希望之后将嵌套数据框简化为字符向量,例如。

library(tidyverse)

items <- tibble(name1 = c("Item1", "Item2"), 
                name2 = c("ItemID1", "ItemID2"), 
                imgID = c("Img1", "Img2"), 
                attr1 = c("water", "cocoa"), 
                attr2 = c("chocolate", "spice"), 
                attr3 = c("soy", "milk"))

items_nested <- items %>% 
    nest(contains('attr'), .key = 'attr') %>% 
    mutate(attr = map(attr, simplify))

items_nested
#> # A tibble: 2 x 4
#>   name1 name2   imgID attr     
#>   <chr> <chr>   <chr> <list>   
#> 1 Item1 ItemID1 Img1  <chr [3]>
#> 2 Item2 ItemID2 Img2  <chr [3]>

其他选项包括使用tidyr::gather重新整理为长整数,除了新列以外的所有列进行分组,并将值列聚合为更加专注于dplyr的样式的列表:

items %>% 
    gather(attr_num, attr, contains('attr')) %>% 
    group_by_at(vars(-attr_num, -attr)) %>% 
    summarise(attr = list(attr)) %>% 
    ungroup()

unite attr*列,然后使用strsplit在列表列中以更加以字符串为重点的方式将它们分开:

items %>% 
    unite(attr, contains('attr')) %>% 
    mutate(attr = strsplit(attr, '_'))

或以列表为重点的风格使用purrr::transpose和tidyselect:

items %>% 
    mutate(attr = transpose(select(., contains('attr')))) %>% 
    select(-matches('attr.'))

所有选项都返回相同的内容,至少在样本数据上。进一步清理,例如删除NA,可以通过使用lapply / purrr::map迭代新列来完成。