Faceți matrice de caractere 0/1 din arborele filogenetic aleatoriu în R? (Programare, R, Filogenie, Maimuță Phylo)

Michael S Taylor a intrebat.
a intrebat.

Este posibil să se genereze 0/1 matrici de caractere precum cele prezentate mai jos în dreapta din arbori filogenetici bifurcați precum cei din stânga. 1 din matrice indică prezența unui caracter comun care unește cladele.

Acest cod generează arbori aleatori frumoși, dar nu am nicio idee de unde să încep să transform rezultatele într-o matrice de caractere.

library(ape) # Other package solutions are acceptable

forest <- rmtree(N = 2, n = 10, br = NULL)
plot(forest)

Pentru a fi clar, pot utiliza următorul cod pentru a genera matrici aleatoare și apoi să reprezint arborii.

library(ape)
library(phangorn)

ntaxa <- 10
nchar <- ntaxa - 1

char_mat <- array(0, dim = c(ntaxa, ntaxa - 1))

for (i in 1:nchar) {
  char_mat[,i] <- replace(char_mat[,i], seq(1, (ntaxa+1)-i), 1)
}

char_mat <- char_mat[sample.int(nrow(char_mat)), # Shuffle rows 
                     sample.int(ncol(char_mat))] # and cols

# Ensure all branch lengths > 0
dist_mat <- dist.gene(char_mat) + 0.5
upgma_tree <- upgma(dist_mat)
plot.phylo(upgma_tree, "phylo")

Ceea ce vreau este să generez arbori aleatori, iar apoi să fac matrici din acești arbori. Această soluție nu creează tipul corect de matrice.

Editare pentru claritate: Eu generez matrici de caractere binare pe care studenții le pot folosi pentru a trasa arbori filogenetici folosind parsimonia simplă. 1 caracter reprezintă omologiile care unesc taxonii în clade. Astfel, toate rândurile trebuie să aibă în comun un caracter (a 1 pe toate rândurile dintr-o coloană), iar unele caractere trebuie să fie împărtășite de numai doi taxoni. (Fac abstracție de autapomorfii).

Exemple:

2 răspunsuri
Thomas Guillerme

puteți arunca o privire la rTraitDisc din ape care este destul de simplă:

library(ape)
## You'll need to simulate branch length!
forest <- rmtree(N = 2, n = 10)

## Generate on equal rate model character
(one_character <- rTraitDisc(forest[[1]], type = "ER", states = c(0,1)))
# t10  t7  t5  t9  t1  t4  t2  t8  t3  t6 
#   0   0   0   1   0   0   0   0   0   0 
# Levels: 0 1

## Generate a matrix of ten characters
(replicate(10, rTraitDisc(forest[[1]], type = "ER", states = c(0,1))))

#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# t10 "0"  "0"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  
# t7  "0"  "0"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  
# t5  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t9  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t1  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t4  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t2  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t8  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t3  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t6  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"

Pentru a o aplica la mai mulți arbori, cel mai bine ar fi să creați o funcție lapply astfel:

## Lapply wrapper function
generate.characters <- function(tree) {
    return(replicate(10, rTraitDisc(tree, type = "ER", states = c(0,1))))
}

## Generate 10 character matrices for each tree
lapply(forest, generate.characters)

# [[1]]
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# t10 "0"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  
# t7  "0"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  
# t5  "0"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  
# t9  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t1  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t4  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t2  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t8  "0"  "0"  "0"  "1"  "0"  "1"  "0"  "0"  "0"  "1"  
# t3  "0"  "0"  "0"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  
# t6  "0"  "0"  "0"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  

# [[2]]
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# t7  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t9  "1"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t5  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t2  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t4  "0"  "1"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  
# t6  "0"  "1"  "0"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  
# t10 "0"  "1"  "1"  "0"  "1"  "1"  "0"  "0"  "0"  "1"  
# t8  "0"  "1"  "1"  "0"  "1"  "0"  "0"  "0"  "0"  "0"  
# t3  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  
# t1  "0"  "1"  "0"  "0"  "0"  "0"  "0"  "0"  "0"  "0" 

O altă opțiune este să folosiți funcția sim.morpho din dispRity pachet. Această funcție reutilizează funcția rTraitDisc dar are ceva mai multe modele implementate și permite ca ratele să fie furnizate ca distribuții din care să se eșantioneze. De asemenea, permite ca caracterele să arate puțin mai „realiste” fără prea multe date invariante și asigurându-se că caracterul generat „arată” ca un caracter morfologic real (de exemplu, cu o cantitate corectă de homoplastie etc.).

library(dispRity)
## You're first tree
tree <- forest[[1]]
## Setting up the parameters
my_rates = c(rgamma, rate = 10, shape = 5)
my_substitutions = c(runif, 2, 2)

## HKY binary (15*50)
matrixHKY <- sim.morpho(tree, characters = 50, model = "HKY",
     rates = my_rates, substitution = my_substitutions)

## Mk matrix (15*50) (for Mkv models)
matrixMk <- sim.morpho(tree, characters = 50, model = "ER", rates = my_rates) 

## Mk invariant matrix (15*50) (for Mk models)
matrixMk <- sim.morpho(tree, characters = 50, model = "ER", rates = my_rates,
     invariant = FALSE)

## MIXED model invariant matrix (15*50)
matrixMixed <- sim.morpho(tree, characters = 50, model = "MIXED",
     rates = my_rates, substitution = my_substitutions,  invariant = FALSE,
     verbose = TRUE)

Vă sugerez să consultați pagina sim.morpho funcție pentru referințele adecvate privind modul în care funcționează modelul sau la secțiunea relevantă din manualul pachetului dispRity.

Comentarii

  • Vă mulțumesc, dar acest lucru nu servește nevoilor mele. rTraitDisc generează trăsături aleatorii care au evoluat în puncte de-a lungul arborelui, dar nu pot fi folosite pentru a asambla arborele, care este ceea ce am nevoie. Îmi pare rău că nu am fost clar; și am încercat să clarific. Cu toate acestea, răspunsul dumneavoastră îmi dă idei pentru direcții viitoare! –  > Por Michael S Taylor.
Michael S Taylor

Mi-am dat seama cum să fac matricea folosind Descendants din phangorn pachet. Încă mai trebuie să o ajustez cu etichete de nod adecvate pentru a se potrivi cu matricea de exemplu din întrebarea originală, dar cadrul este acolo.

library(ape)
library(phangorn)

ntaxa <- 8
nchar <- ntaxa - 1

tree <- rtree(ntaxa, br = NULL)

# Gets descendants, but removes the first ntaxa elements,
# which are the individual tips
desc <- phangorn::Descendants(tree)[-seq(1, ntaxa)]

char_mat <- array(0, dim = c(ntaxa, nchar))

for (i in 1:nchar) {
  char_mat[,i] <- replace(char_mat[,i], y <- desc[[i]], 1)
}

rownames(char_mat) <- tree$tip.label
char_mat
#>    [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> t6    1    1    0    0    0    0    0
#> t3    1    1    1    0    0    0    0
#> t7    1    1    1    1    0    0    0
#> t2    1    1    1    1    1    0    0
#> t5    1    1    1    1    1    0    0
#> t1    1    0    0    0    0    1    1
#> t8    1    0    0    0    0    1    1
#> t4    1    0    0    0    0    1    0

plot(tree)

Creat la 2019-01-28 de către pachetul reprex (v0.2.1)