我有一个包含多个条目的列表,示例条目如下:
> 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
谢谢!
答案 0 :(得分:1)
以下是tidyverse
和purrr
的解决方案。我扩展了示例输入以生成示例输出。这里的关键功能是imap
,它是map2(x, seq_along(x))
的简写。有关详情,请参阅help。我们想要做的是将一个函数应用于列表和其索引中的每个数据帧。所以我们使用函数~ tibble(set_index = .y, gene = colnames(.x[4:ncol(.x)]))
。
~
,.x
和.y
是purrr
,function(x, y)
和x
的{{1}}个缩写。这让我们可以紧凑地引用函数的参数。请参阅y
。?map2
创建第一列并使用当前数据框的索引填充它(它有用地重复为正确的长度)set_index = .y
从基因名称的向量中创建第二列。 gene = colnames(.x[4:ncol(.x)]))
获取数据框的变量名称,但我们将其子集排除前三个。colnames
,我们会得到一个数据框列表。 imap
只接受该列表并将它们作为行绑定在一起,从而产生所需的输出。 (相当于之后调用imap_dfr
)bind_rows
由reprex package(v0.2.0)创建于2018-03-02。