R; DPLYR:将数据帧列表转换为单个有组织的数据帧
R; DPLYR: Convert a list of dataframes into a single organized dataframe
我有一个包含多个条目的列表,示例条目如下所示:
> 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
谢谢!
这是 tidyverse
和 purrr
的解决方案。我扩展了示例输入以生成示例输出。这里的关键函数是imap
,也就是shorthand for map2(x, seq_along(x))
。有关更多信息,请参阅 help。我们想要做的是将一个函数应用于列表 和 其索引中的每个数据帧。所以我们使用函数 ~ tibble(set_index = .y, gene = colnames(.x[4:ncol(.x)]))
.
~
、.x
和 .y
是 purrr
shorthands for function(x, y)
、x
和 y
.这让我们可以紧凑地引用函数的参数。参见 ?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 (v0.2.0) 创建于 2018-03-02。
我有一个包含多个条目的列表,示例条目如下所示:
> 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
谢谢!
这是 tidyverse
和 purrr
的解决方案。我扩展了示例输入以生成示例输出。这里的关键函数是imap
,也就是shorthand for map2(x, seq_along(x))
。有关更多信息,请参阅 help。我们想要做的是将一个函数应用于列表 和 其索引中的每个数据帧。所以我们使用函数 ~ tibble(set_index = .y, gene = colnames(.x[4:ncol(.x)]))
.
~
、.x
和.y
是purrr
shorthands forfunction(x, y)
、x
和y
.这让我们可以紧凑地引用函数的参数。参见?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 (v0.2.0) 创建于 2018-03-02。