R等DPLYR:将数据帧列表转换为单个有组织的数据帧

问题描述 投票:0回答:1

我有一个包含多个条目的列表,示例条目如下所示:

> head(gene_sets[[1]])
     patient Diagnosis Eigen_gene ENSG00000080824 ENSG00000166165 ENSG00000211459 ENSG00000198763 ENSG00000198938 ENSG00000198886
1 689_120604        AD -0.5606425           50137           38263          309298          528233          523420          730537
2 412_120503        AD  0.9454632           44536           23333          404316          730342          765963         1168123
3 706_120605        AD  0.6061834           16647           22021          409498          614314          762878         1171747
4 486_120515        AD  0.8164779           21871            9836          518046          697051          613621         1217262
5 469_120514        AD  0.5354927           33460           11651          468223          653745          608259         1115973
6 369_120502        AD -0.8363372           32168           44760          271978          436132          513194          784537

对于这些条目,前三列始终保持一致,并且列总数不同。

我想要做的是将整个列表转换为数据帧。我需要保留的信息是set_index是列表中的条目索引,然后是Eigen_gene之外的所有组合名称,直到最后一列。

我可以想到使用循环的解决方案,但我想要一个dplyr/reshape解决方案。

澄清一下,如果我们有一个假的输入看起来像:

> list(data.frame(patient= c(1,2,3), Diagnosis= c("AD","Control", "AD"), Eigen_gene= c(1.1, 2.3, 4.3), geneA= c(1,1,1), geneC= c(2,1,3), geneB= c(2,39,458)))
[[1]]
  patient Diagnosis Eigen_gene geneA geneC geneB
1       1        AD        1.1     1     2     2
2       2   Control        2.3     1     1    39
3       3        AD        4.3     1     3   458

所需的输出看起来像这样(我只显示了输入的第一个列表条目的示例,输出显示了列表中的其他条目也将如何格式化):

> data.frame(set_index= c(1,1,1,2,2,2,3,3), gene= c("geneA", "geneC", "geneB", "geneF", "geneE", "geneH", "geneT", "geneZ"))
  set_index  gene
1         1 geneA
2         1 geneC
3         1 geneB
4         2 geneF
5         2 geneE
6         2 geneH
7         3 geneT
8         3 geneZ

谢谢!

r dplyr data-cleaning
1个回答
1
投票

这是来自tidyversepurrr的解决方案。我扩展了示例输入以生成示例输出。这里的关键功能是imap,它是map2(x, seq_along(x))的简写。有关更多信息,请参阅help。我们想要做的是将函数应用于列表中的每个数据帧及其索引。所以我们使用函数~ tibble(set_index = .y, gene = colnames(.x[4:ncol(.x)]))

  • ~.x.ypurrrfunction(x, y)xy短锋。这让我们可以紧凑地引用函数的参数。见?map2
  • set_index = .y创建第一列并用当前数据帧的索引填充它(它有用地重复为正确的长度)
  • gene = colnames(.x[4:ncol(.x)]))从基因名称的载体中创建第二列。 colnames获取数据框的变量名称,但我们将子集排除前三个。
  • 如果我们只有imap,我们会得到一个数据框列表。 imap_dfr只取这个列表并将它们绑定在一起作为行,产生我们想要的输出。 (相当于之后调用bind_rows
library(tidyverse)
gene_list <- list(
  data.frame(
    patient= c(1,2,3),
    Diagnosis= c("AD","Control", "AD"),
    Eigen_gene= c(1.1, 2.3, 4.3),
    geneA= c(1,1,1),
    geneC= c(2,1,3),
    geneB= c(2,39,458)
  ),
  data.frame(
    patient= c(1,2,3),
    Diagnosis= c("AD","Control", "AD"),
    Eigen_gene= c(1.1, 2.3, 4.3),
    geneF= c(1,1,1),
    geneE= c(2,1,3),
    geneH= c(2,39,458)
  ),
  data.frame(
    patient= c(1,2,3),
    Diagnosis= c("AD","Control", "AD"),
    Eigen_gene= c(1.1, 2.3, 4.3),
    geneT= c(1,1,1),
    geneZ= c(2,1,3)
  )
)

output <- gene_list %>%
  imap_dfr(~ tibble(set_index = .y, gene = colnames(.x[4:ncol(.x)])))
output
#> # A tibble: 8 x 2
#>   set_index gene 
#>       <int> <chr>
#> 1         1 geneA
#> 2         1 geneC
#> 3         1 geneB
#> 4         2 geneF
#> 5         2 geneE
#> 6         2 geneH
#> 7         3 geneT
#> 8         3 geneZ

reprex package创建于2018-03-02(v0.2.0)。

© www.soinside.com 2019 - 2024. All rights reserved.