【问题标题】:How to combine multiple columns of an r data frame into a single column that is a list如何将 r 数据框的多列组合成一个列表
【发布时间】:2018-02-17 01:22:12
【问题描述】:

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

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 值?

【问题讨论】:

    标签: r list dataframe nested-lists


    【解决方案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 将其重新整形为 long,按除新列之外的所有列进行分组,以及以更注重 dplyr 的样式将 value 列聚合到列表中:

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

    uniteattr* 列,然后以更注重字符串的样式将它们分隔在一个列表列中,strsplit

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

    或以列表为中心的样式使用purrr::transpose 和 tidyselect:

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

    所有选项都返回相同的东西,至少在样本数据上是这样。进一步清理,例如删除 NAs,可以通过使用 lapply/purrr::map 遍历新列来完成。

    【讨论】:

    • 当您有一些为空的行或它们没有全部填充值时,这是否有效?例如,我的一些项目没有相同数量的 attr。当我尝试第一种方法时,我收到以下消息:' mutate_impl(.data, dots) 中的错误:评估错误:参数长度为零。另外:警告消息:1:在 min(x, na.rm = na.rm) 中:min 没有非缺失参数;返回 Inf'
    • 您可以将NAs 与mutate(attr = map(attr, na.omit)) 或类似内容一起删除,但鉴于警告部分,您仍然必须考虑到之后列表元素中没有任何内容的可能性总结一下,例如通过使用map 中的控制流,例如map(attr, ~if(length(.x) == 0 NA else ...)
    猜你喜欢
    • 1970-01-01
    • 2021-10-18
    • 1970-01-01
    • 2020-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多