【问题标题】:Turn a nested list of (taxize) taxonomy data into a data frame将(分类)分类数据的嵌套列表转换为数据框
【发布时间】:2018-03-23 14:13:41
【问题描述】:

我有一些生物学(微生物组)数据,其中有一堆 OTU,它们具有单一名称,它们的分类分辨率在属和门级别之间有所不同。我正在尝试获取所有比我给出的名称更低级别的分类表。

 testnames <- c("Prevotella", "Bacteroides", "Enterobacteriaceae")

我发现 taxize 是一个有用的包,可用于提取我正在寻找的信息。

library("taxize")
reclass <- classification(testnames, db = 'ncbi')

这让我得到一个数据框列表

看起来像这样:

并且可以这样输入到R中:

structure(list(Prevotella = structure(list(name = c("cellular organisms", 
"Bacteria", "FCB group", "Bacteroidetes/Chlorobi group", "Bacteroidetes", 
"Bacteroidia", "Bacteroidales", "Prevotellaceae", "Prevotella"
), rank = c("no rank", "superkingdom", "no rank", "no rank", 
"phylum", "class", "order", "family", "genus"), id = c("131567", 
"2", "1783270", "68336", "976", "200643", "171549", "171552", 
"838")), .Names = c("name", "rank", "id"), row.names = c(NA, 
-9L), class = "data.frame"), Bacteroides = structure(list(name = c("cellular organisms", 
"Bacteria", "FCB group", "Bacteroidetes/Chlorobi group", "Bacteroidetes", 
"Bacteroidia", "Bacteroidales", "Bacteroidaceae", "Bacteroides"
), rank = c("no rank", "superkingdom", "no rank", "no rank", 
"phylum", "class", "order", "family", "genus"), id = c("131567", 
"2", "1783270", "68336", "976", "200643", "171549", "815", "816"
)), .Names = c("name", "rank", "id"), row.names = c(NA, -9L), class = "data.frame"), 
    Enterobacteriaceae = structure(list(name = c("cellular organisms", 
    "Bacteria", "Proteobacteria", "Gammaproteobacteria", "Enterobacterales", 
    "Enterobacteriaceae"), rank = c("no rank", "superkingdom", 
    "phylum", "class", "order", "family"), id = c("131567", "2", 
    "1224", "1236", "91347", "543")), .Names = c("name", "rank", 
    "id"), row.names = c(NA, -6L), class = "data.frame")), .Names = c("Prevotella", 
"Bacteroides", "Enterobacteriaceae"))

我真的很想把东西变成一个数据框,我可以将它作为分类表导入到 phyloseq 中。例如。看起来像的东西:

命名门类目科属

Prevotella Bacteroidetes Bacteroidas Bacteroidales Prevotellaceae Prevotella

Bacteroides Bacteroidetes Bacteroida Bacteroidales Bacteroides Bacteroides Bacteroides

肠杆菌科 Proteobacteria Gammaproteobacteria Enterobacterales Enterobacteriaceae

当然,这样做的一种方法是创建一个循环,该循环遍历列表的每个元素,找到被调用的变量 phylum,然后将其放入新的数据帧中。也就是说,我觉得应该有一种更快的方法来应用这种转换,使用 plyr 或 dplyr 之类的东西。

我看到了一些看起来很接近的东西:

Converting nested list to dataframe

Turn a list of lists with unnamed entries into a data frame or a tibble

但他们似乎假设不想保存的数据更少,并且每个元素的数据帧大小均匀。有什么建议吗?

【问题讨论】:

    标签: r dplyr plyr


    【解决方案1】:

    使用dplyrtidyr

    library(dplyr)
    library(tidyr)
    
    tibble(names = names(list), list) %>% 
      unnest() %>% 
      filter(rank %in% c("phylum","class","order","family","genus")) %>% 
      select(-id) %>% 
      spread(rank, name) %>% 
      select(name = names, phylum, class, order, family, genus)
    
    # A tibble: 3 × 6
                    name         phylum               class            order             family       genus
    *              <chr>          <chr>               <chr>            <chr>              <chr>       <chr>
    1        Bacteroides  Bacteroidetes         Bacteroidia    Bacteroidales     Bacteroidaceae Bacteroides
    2 Enterobacteriaceae Proteobacteria Gammaproteobacteria Enterobacterales Enterobacteriaceae        <NA>
    3         Prevotella  Bacteroidetes         Bacteroidia    Bacteroidales     Prevotellaceae  Prevotella
    

    这是做什么的:

    1. 用列表名称和每个嵌套列表创建一个tibble
    2. 取消嵌套列表
    3. 在排名列中过滤您想要的值
    4. 去掉id列
    5. 将排名行分散到列中,并用 name 中的值填充
    6. 选择您想要的顺序,将名称重命名为名称。

    【讨论】:

    • 感谢@Jake Kaupp 的建议。出于某种原因,当我将其应用于我的数据时,我陷入了本练习的 unnest() 部分。如果我从我的数据中运行list = reclass,然后运行您建议的代码,我会收到一个错误,开头为“bind_rows_(x, .id) 中的错误:参数 1 必须是数据帧或命名的原子向量,而不是分类”。如果我在 unnest() 函数之后停止,我也会收到此错误。我错过了什么吗?
    • unnest() 部分神秘地自行修复,但现在过滤器似乎不起作用。具体来说,ldata &lt;- tibble(names = names(reclass), reclass) %&gt;% unlist() 返回一类“字符”,然后当我尝试过滤它时。 dplyr::filter(ldata, rank %in% c("phylum","class","order","family","genus")) 我在 UseMethod("filter_") 中遇到错误:没有适用于 'filter_' 的方法应用于“字符”类的对象。如果我按照编写的方式运行您的代码,也会发生这种情况。
    • 我的解决方案中没有unlist()unnestunlist() 非常不同
    • 嗯。我正在运行 tridyr_0.7.0dplyr_0.7.2
    • 啊,这就是它神奇地开始工作的原因。这是因为我从输入 unnest 到输入 unlist。所以这行得通,但没有给过滤器它所期望的东西。所以这让我回到了为什么 unnest() 不起作用。因此,如果我运行 ldata &lt;- tibble(names = names(reclass), reclass) 然后 unnest(ldata) R 抱怨错误在 bind_rows_(x, .id): Argument 1 must be a data frame or a named atomic vector,而不是分类。但是如果我检查 ldata class(ldata) 的类,我会得到 'tbl_df' 'tbl' 'data.frame'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-22
    • 2020-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多