5

我有几个包含发现它们的物种名称的基因字符向量,我制作了一个 UpSetR 图来显示基因中共有物种的数量。现在我想做相反的事情:绘制跨物种共同基因的数量,但我不知道该怎么做。

我所拥有的示例:

gene1 <- c("Panda", "Dog", "Chicken")
gene2 <- c("Human", "Panda", "Dog")
gene3 <- c("Human", "Panda", "Chicken")  
...#About 20+ genes with 100+ species each

我想要的结果示例:

Panda <- c("gene1", "gene2", "gene3")
Dog <- c("gene1", "gene2")
Human <- c("gene2", "gene3")
Chicken <- c("gene1", "gene3")
...  

我知道这在概念上很容易,但在逻辑上更复杂。谁能给我一个线索?

谢谢!

4

5 回答 5

8

您可以unstack从基础 R 使用:

unstack(stack(mget(ls(pattern="gene"))),ind~values)
$Chicken
[1] "gene1" "gene3"

$Dog
[1] "gene1" "gene2"

$Human
[1] "gene2" "gene3"

$Panda
[1] "gene1" "gene2" "gene3"

您最终可以按list2env功能将其列出到环境中

分解:

 l = mget(ls(pattern="gene"))#get all the genes in a list
 m = unstack(stack(l),ind~values)# Stack them, then unstack with the required formula
 m
$Chicken
[1] "gene1" "gene3"

$Dog
[1] "gene1" "gene2"

$Human
[1] "gene2" "gene3"

$Panda
[1] "gene1" "gene2" "gene3"

 list2env(m,.GlobalEnv)
 Dog
 [1] "gene1" "gene2"
于 2018-03-19T19:27:04.497 回答
3

首先将数据放入列表中。这使得使用起来更容易。

genes <- list(
    gene1 = c("Panda", "Dog", "Chicken"),
    gene2 = c("Human", "Panda", "Dog"),
    gene3 = c("Human", "Panda", "Chicken")
)

然后我们可以从那里得到物种名称。

species <- unique(unlist(genes))

有了这个数据

> species
[1] "Panda"   "Dog"     "Chicken" "Human" 

对于其中的每一个,我们要检查名称是否包含在基因中。这是一份工作Map(或其表弟lapply,但我喜欢Map):

get_genes_for_species <- function(s) {
    contained <- unlist(Map(function(gene) s %in% gene, genes))
    names(genes)[contained]
}
genes_per_species <- Map(get_genes_for_species, species)

现在你有一个列表列表,每个物种一个列表,包含在该物种中发现的基因。

> genes_per_species
$Panda
[1] "gene1" "gene2" "gene3"

$Dog
[1] "gene1" "gene2"

$Chicken
[1] "gene1" "gene3"

$Human
[1] "gene2" "gene3"
于 2018-03-19T19:49:59.180 回答
3

首先,我认为对于大多数目的,最好将gene向量存储在列表中,如

genes <- list(gene1 = gene1, gene2 = gene2, gene3 = gene3)

然后一种基本的 R 方法是

genes.v <- unlist(genes)
names(genes.v) <- rep(names(genes), times = lengths(genes))
species <- lapply(unique(genes.v), function(g) names(genes.v)[g == genes.v])
names(species) <- unique(genes.v)
species
# $Panda
# [1] "gene1" "gene2" "gene3"
#
# $Dog
# [1] "gene1" "gene2"
#
# $Chicken
# [1] "gene1" "gene3"
#
# $Human
# [1] "gene2" "gene3"

genes.v是所有物种的命名向量,基因是它们的名字。但是,当物种具有相同的名称时,例如gene1,那么这些名称是gene11gene12。这就是我在第二行中解决的问题。然后在第三行我检查所有物种并创建结果列表,除了在第四行我添加物种名称。

于 2018-03-19T19:25:57.553 回答
1

你可以试试这个。

gene  <-unique(c(gene1,gene2,gene3))
TF    <-data.frame(Species = gene)

TF$gene1 <- gene%in%gene1
TF$gene2 <- gene%in%gene2
TF$gene3 <- gene%in%gene3

> TF
  Species gene1 gene2 gene3
1   Panda  TRUE  TRUE  TRUE
2     Dog  TRUE  TRUE FALSE
3 Chicken  TRUE FALSE  TRUE
4   Human FALSE  TRUE  TRUE
于 2018-03-19T19:23:02.447 回答
1

这是一个包含 tidyverse 并将结果放在一个整洁的数据框中的变体。

诀窍是将结果与str_c和连接起来summarise

   tibble(gene1 = gene1, 
          gene2 = gene2, 
          gene3 = gene3) %>% 
   gather(gene_name, gene_type) %>% 
   group_by(gene_type) %>% 
   summarise(genes = str_c(gene_name, collapse = ", "))

# A tibble: 4 x 2
  gene_type genes              
  <chr>     <chr>              
1 Chicken   gene1, gene3       
2 Dog       gene1, gene2       
3 Human     gene2, gene3       
4 Panda     gene1, gene2, gene3

我同意 Julius(上图)的观点,即存储基因载体的最佳方式是使用列表。命名列表会更好,因为:

my_gene_list <- set_names(list(gene1, gene2, gene3), str_c("gene", 1:3) ) 

这将巧妙地产生相同的结果......

 my_gene_list %>% as_tibble() %>% 
   gather(gene_name, gene_type) %>% 
   group_by(gene_type) %>% 
   summarise(genes = str_c(gene_name, collapse = ", "))

# A tibble: 4 x 2
  gene_type genes              
  <chr>     <chr>              
1 Chicken   gene1, gene3       
2 Dog       gene1, gene2       
3 Human     gene2, gene3       
4 Panda     gene1, gene2, gene3
于 2018-09-16T18:41:00.840 回答