2017-08-02 94 views
4

我有以下列表的列表。它包含两个变量:pair和基因。 pair的包含总是带有两个字符串的向量。变量genes是一个可以包含多个值的向量。如何将列表的列表转换为一个tibble(数据框)


lol <- list(structure(list(pair = c("BoneMarrow", "Pulmonary"), genes = "PRR11"), .Names = c("pair", 
"genes")), structure(list(pair = c("BoneMarrow", "Umbilical"), 
    genes = "GNB2L1"), .Names = c("pair", "genes")), structure(list(
    pair = c("Pulmonary", "Umbilical"), genes = "ATP1B1"), .Names = c("pair", 
"genes"))) 


lol 
#> [[1]] 
#> [[1]]$pair 
#> [1] "BoneMarrow" "Pulmonary" 
#> 
#> [[1]]$genes 
#> [1] "PRR11" 
#> 
#> 
#> [[2]] 
#> [[2]]$pair 
#> [1] "BoneMarrow" "Umbilical" 
#> 
#> [[2]]$genes 
#> [1] "GNB2L1" 
#> 
#> 
#> [[3]] 
#> [[3]]$pair 
#> [1] "Pulmonary" "Umbilical" 
#> 
#> [[3]]$genes 
#> [1] "ATP1B1" 

我怎样才能将其转换成数据帧这样:

pair1   pair2  genes_vec 
BoneMarrow Pulmonary PRR11 
BoneMarrow Umbilical GNB2L1 
Pulmonary  Umbilical ATP1B1 

注意,genes变量是一个向量不是单一的字符串。

我最好的尝试是这里面并没有给我想要的:

> do.call(rbind, lapply(lol, data.frame, stringsAsFactors=FALSE)) 
     pair genes 
1 BoneMarrow PRR11 
2 Pulmonary PRR11 
3 BoneMarrow GNB2L1 
4 Umbilical GNB2L1 
5 Pulmonary ATP1B1 
6 Umbilical ATP1B1 

更新

有了新的例子来说明的矢量内容genes

lol2 <- list(structure(list(pair = c("BoneMarrow", "Pulmonary"), genes = c("GNB2L1", 
"PRR11")), .Names = c("pair", "genes")), structure(list(pair = c("BoneMarrow", 
"Umbilical"), genes = "GNB2L1"), .Names = c("pair", "genes")), 
    structure(list(pair = c("Pulmonary", "Umbilical"), genes = "ATP1B1"), .Names = c("pair", 
    "genes"))) 

lol2 
#> [[1]] 
#> [[1]]$pair 
#> [1] "BoneMarrow" "Pulmonary" 
#> 
#> [[1]]$genes 
#> [1] "GNB2L1" "PRR11" 
#> 
#> 
#> [[2]] 
#> [[2]]$pair 
#> [1] "BoneMarrow" "Umbilical" 
#> 
#> [[2]]$genes 
#> [1] "GNB2L1" 
#> 
#> 
#> [[3]] 
#> [[3]]$pair 
#> [1] "Pulmonary" "Umbilical" 
#> 
#> [[3]]$genes 
#> [1] "ATP1B1" 

预期的输出是:

pair1   pair2  genes_vec 
BoneMarrow Pulmonary PRR11,GNB2L1 
BoneMarrow Umbilical GNB2L1 
Pulmonary  Umbilical ATP1B1 

回答

1
> lol1 <- data.frame(t(sapply(lol,c))) 
> as.data.frame(t(apply(lol1, 1, unlist))) 
     pair1  pair2 genes 
1 BoneMarrow Pulmonary PRR11 
2 BoneMarrow Umbilical GNB2L1 
3 Pulmonary Umbilical ATP1B1 
+0

谢谢。不完全是我想要的,我怎样才能进一步将这一对分成两列? – scamander

+0

@yaffle更新了解决方案 – RUser

+0

谢谢,但是当'基因'是一个向量时,你的最新方法似乎失败了。看到我的更新 – scamander

1

编辑:更新了矢量lol2工作。

也许是这样的:

as.data.frame(do.call(rbind,lapply(lol2, function(x) {c(unlist(x[1]),gene=paste(unlist(x[2]),collapse=","))})),stringsAsFactors = F) 




     pair1  pair2   genes 
1 BoneMarrow Pulmonary GNB2L1, PRR11 
2 BoneMarrow Umbilical  GNB2L1 
3 Pulmonary Umbilical  ATP1B1 
+0

谢谢。当'基因'是一个载体时,你的方法似乎失败了。查看我的更新。 – scamander

+1

更新了我的回答 – Florian

+0

谢谢你有一种方法来简化你的最后输出到简单的数据框只有3个变量(列)。现在'str()'显示数据帧包含*嵌套*列表。为了进一步检查你可以尝试'as.tibble(your_outpput)'。 – scamander

3

使用tidyverse,你可以使用purrr来帮助你


library(dplyr) 
library(purrr) 

tibble(
    pair = map(lol, "pair"), 
    genes_vec = map_chr(lol, "genes") 
) %>% 
    mutate(
    pair1 = map_chr(pair, 1), 
    pair2 = map_chr(pair, 2) 
) %>% 
    select(pair1, pair2, genes_vec) 
#> # A tibble: 3 x 3 
#>  pair1  pair2 genes_vec 
#>  <chr>  <chr>  <chr> 
#> 1 BoneMarrow Pulmonary  PRR11 
#> 2 BoneMarrow Umbilical GNB2L1 
#> 3 Pulmonary Umbilical ATP1B1 

无线第二个示例中,只需将map_chr(lol, "genes")替换为map(lol2, "genes"),因为您希望保留具有列表列的嵌套数据帧。


tibble(
    pair = map(lol2, "pair"), 
    genes_vec = map(lol2, "genes") 
) %>% 
    mutate(
    pair1 = map_chr(pair, 1), 
    pair2 = map_chr(pair, 2) 
) %>% 
    select(pair1, pair2, genes_vec) 
#> # A tibble: 3 x 3 
#>  pair1  pair2 genes_vec 
#>  <chr>  <chr> <list> 
#> 1 BoneMarrow Pulmonary <chr [2]> 
#> 2 BoneMarrow Umbilical <chr [1]> 
#> 3 Pulmonary Umbilical <chr [1]> 

,并根据需要

library(dplyr) 
library(purrr) 
library(tidyr) 

tab1 <-lol %>% 
    transpose() %>% 
    as_tibble() %>% 
    mutate(pair = map(pair, ~as_tibble(t(.x)))) %>% 
    mutate(pair = map(pair, ~set_names(.x, c("pair1", "pair2")))) 
tab1 
#> # A tibble: 3 x 2 
#>    pair  genes 
#>    <list> <list> 
#> 1 <tibble [1 x 2]> <chr [1]> 
#> 2 <tibble [1 x 2]> <chr [1]> 
#> 3 <tibble [1 x 2]> <chr [1]> 

对于lol2没有一个比较通用的做法是嵌套tibbles工作和UNNEST他们的变化,除非该列表lol2而不是lol1

tab2 <- lol2 %>% 
    transpose() %>% 
    as_tibble() %>% 
    mutate(pair = map(pair, ~as_tibble(t(.x)))) %>% 
    mutate(pair = map(pair, ~set_names(.x, c("pair1", "pair2")))) 
tab2 
#> # A tibble: 3 x 2 
#>    pair  genes 
#>    <list> <list> 
#> 1 <tibble [1 x 2]> <chr [2]> 
#> 2 <tibble [1 x 2]> <chr [1]> 
#> 3 <tibble [1 x 2]> <chr [1]> 

然后,您可以UNNEST你想要的列

tab1 %>% 
    unnest() 
#> # A tibble: 3 x 3 
#> genes  pair1  pair2 
#> <chr>  <chr>  <chr> 
#> 1 PRR11 BoneMarrow Pulmonary 
#> 2 GNB2L1 BoneMarrow Umbilical 
#> 3 ATP1B1 Pulmonary Umbilical 

tab2 %>% 
    unnest(pair) 
#> # A tibble: 3 x 3 
#>  genes  pair1  pair2 
#>  <list>  <chr>  <chr> 
#> 1 <chr [2]> BoneMarrow Pulmonary 
#> 2 <chr [1]> BoneMarrow Umbilical 
#> 3 <chr [1]> Pulmonary Umbilical 
0

这应该工作:

data.frame(do.call(rbind,lol2)) 
data.frame(do.call(rbind,lol2)) 
        pair   genes 
1 BoneMarrow, Pulmonary GNB2L1, PRR11 
2 BoneMarrow, Umbilical  GNB2L1 
3 Pulmonary, Umbilical  ATP1B1 

您治疗的基因以同样的方式作为载体是可以以同样的方式同样的方式,你可以把这些对作为一个向量..而不是对1和2,你只是使用它们两个。