Nota: El contenido de este cuaderno proviene de clases del profesor Luis Fernando García, del departamento de Biología de la Universidad Nacional de Colombia.
La librería phytools
es usada para visualizar árboles.
library(ape)
library(phangorn)
library(phytools)
## Loading required package: maps
Vamos a utilizar secuencias del virus de la influenza para diferentes especies. El archivo con dichas secuencias alineadas está en formato fasta y se llama chars2.txt
. Para empezar volvemos el archivo en un formato compatible con la librería phangorn
.
options(width = 300)
= phangorn::read.phyDat(file = "chars2.txt", format = "fasta", type = "DNA")
influenza influenza
## 21 sequences with 1698 character and 217 different site patterns.
## The states are a c g t
Hay 21 secuencias con 1698 caracteres y 217 columnas en las que hay diferentes posiciones. Los estados son adenina timina, etc. Ahora lo que se hace es crear una matriz de distancia para poder crear árboles de distancia o parsimonia a través de ella. En este caso la clase debe ser DNAbin
, por eso transformamos influenza
en este tipo de clase. La función dist.dna
(método o función de objeto o clase) calcula una matriz de distancias por pares de las secuencias de ADN y a partir de una instancia de objecto de clase GNAbin
utilizando un modelo de evolución del ADN (por ejemplo K80, Kimura80).
= ape::as.DNAbin(influenza)
matrizdist = ape::dist.dna(matrizdist)
matrizdist matrizdist
## IV_PATO PATOVIETNAM HUMANO TAIPOLLO VIETNAM MALLARD HONGKONG II_HONGKONG II_POLLO GANSO PATO POLLO III_POLLO II_PATO GANSO_SHANTOU FALCON GORRION II_GORRION III_GORRION CISNE
## PATOVIETNAM 0.024763883
## HUMANO 0.022720037 0.019713335
## TAIPOLLO 0.019746607 0.018724219 0.020719371
## VIETNAM 0.013740529 0.012736124 0.012727193 0.009785048
## MALLARD 0.017721210 0.016707313 0.016695867 0.013740529 0.007805741
## HONGKONG 0.053711759 0.059037274 0.058993731 0.051618174 0.049492772 0.047342246
## II_HONGKONG 0.047376367 0.054781278 0.052606317 0.045302310 0.043201467 0.041080376 0.005843030
## II_POLLO 0.047376367 0.054781278 0.052606317 0.045302310 0.043201467 0.041080376 0.005843030 0.000000000
## GANSO 0.049456414 0.056884418 0.054701859 0.047376367 0.045268882 0.043140541 0.007800249 0.001940571 0.001940571
## PATO 0.049456414 0.056884418 0.054701859 0.047376367 0.045268882 0.043140541 0.007800249 0.001940571 0.001940571 0.000000000
## POLLO 0.062284039 0.065501415 0.063276104 0.058003631 0.055853090 0.060117188 0.068734673 0.062236986 0.062236986 0.064363061 0.064363061
## III_POLLO 0.037034561 0.035969066 0.033878426 0.032924472 0.026776854 0.029817941 0.050480916 0.044187661 0.044187661 0.046257026 0.046257026 0.050446514
## II_PATO 0.042289991 0.041205597 0.041172026 0.038139166 0.031921469 0.034990591 0.053711759 0.047376367 0.047376367 0.049456414 0.049456414 0.056884418 0.022704000
## GANSO_SHANTOU 0.040193552 0.039115729 0.039084341 0.036057997 0.029865968 0.032924472 0.051579559 0.045268882 0.045268882 0.047342246 0.047342246 0.055811457 0.018683878 0.013729173
## FALCON 0.040193552 0.039115729 0.039084341 0.033985455 0.029865968 0.032924472 0.049456414 0.043170243 0.043170243 0.045236980 0.045236980 0.055811457 0.018683878 0.015721207 0.011745043
## GORRION 0.048433450 0.047342246 0.045206605 0.044250785 0.037987655 0.042124218 0.054664481 0.048332346 0.048332346 0.050413658 0.050413658 0.047221117 0.030743211 0.040038709 0.035893608 0.035893608
## II_GORRION 0.035997216 0.034990591 0.036977610 0.033956464 0.027796222 0.031869226 0.039987351 0.033813845 0.033813845 0.035850823 0.035850823 0.047278605 0.026705125 0.031822925 0.027737100 0.027737100 0.021659674
## III_GORRION 0.037005336 0.038014954 0.035917259 0.034962019 0.028795446 0.032873081 0.045236980 0.038999208 0.038999208 0.041052855 0.041052855 0.044104426 0.025678748 0.034885267 0.030778467 0.030778467 0.020666275 0.014695820
## CISNE 0.039115729 0.046429698 0.042185990 0.039148619 0.034990591 0.039115729 0.051618174 0.045302310 0.045302310 0.047376367 0.047376367 0.042154346 0.033855400 0.039054456 0.036977610 0.036977610 0.038973850 0.028774697 0.031822925
## IV_GORRION 0.046429698 0.049570090 0.047412018 0.044356868 0.040159571 0.044319991 0.052725564 0.046392114 0.046392114 0.048470219 0.048470219 0.034909354 0.032849619 0.042219147 0.038043758 0.038043758 0.023660581 0.031822925 0.028737648 0.016734550
Estos árboles son árboles de similaridad, no representan inferencia evolutiva.
Con la matriz de distancia perdemos los caracteres a favor de las diferencias en caracteres entre especies. Cuando aparece un valor de 0, significa que no hay diferencia al nivel de los caracteres (nucléotidos) entre las sequencias de dos especies. Ahora creamos un árbol con el método de grupo de pares no ponderados con media aritmética (UPGMA) usando la matriz de distancia.
= phangorn::upgma(matrizdist)
arbolUPGMA plot(arbolUPGMA)
Si la longitud de dos ramas es indéntica, significa que las secuancias también son indénticas y en la matriz de distancia la diferencia es de 0. Por ejemplo, los virus de influenza de pato y ganso son idénticos.
Ahora hacemos un árbol con el método de unión de vecinos (NJ) usando la misma matriz de distancias:
= nj(matrizdist)
arbolNJ plot(arbolNJ)
Este último árbol puede ser distinto del árbol creado con el método UPGMA. Para personalizar los árboles podemos agregar argumentos a parámetros como cex
, para el tamaño de la letra, edge.color
, para el grosos de las ramas, etc. También se puede escoger entre diferentes visualizaciones de árbol como filograma, cladograma, radial y demás.
plot(arbolUPGMA, type= "p", cex=0.8, edge.width=2, edge.color="red", font=3)
plot(arbolUPGMA, type= "c", cex=0.8, edge.width=2, edge.color="blue", font=3)
plot(arbolUPGMA, type= "p", label.offset=0.0005, edge.lty=1,
node.pos=2, cex=0.8, edge.width=2, edge.color="black", font=3)
phytools
Además de plot
podemos graficar árboles con el método plotTree
del paquete phytools
, el cual es compatible con ape
y con phangorn
.
plotTree(arbolNJ)
A este también le podemos hacer modificaciones.
plotTree(arbolNJ, ftype="b", fsize=0.8, offset=1, color="red", lwd=2)
En los árboles, sin cambiar la topología, se puede cambiar el orden en que los grupos son visualizados. Por ejemplo, se pueden ordena las puntas de manera alfabética (en la medida de lo posible), o con los grupos más derivados hacia uno de los lados del árbo. Para escalarizar hacia la derecha:
plotTree(ladderize(arbolNJ))
Para escalizar hacia la izquierda:
plotTree(ladderize(arbolNJ, right=FALSE))
Fialmente, a notar que para guardar un árbol podemos usar el comando write.tree(tree, file = "file_name.nex")
. Este archivo puede ser leído usando read.tree(file = file_name.nex)
.
Hasta ahora los árboles que hemos construido no están enraízados. Para enraizarlos podemos usar la función root
del paquete ape
. Por ejemplo, para poner por raíz el virus de la influenza presente en humano pasamos por argumento el nombre de la secuencia que corresponde a esta secuencia en el parámetro outgroup
.
<-ape::root(arbolNJ, outgroup = "HUMANO", r = TRUE)
arbolNJraiz plot(arbolNJraiz)
Se puede hacer lo mismo con el árbol creado a partir del método UPGMA.
<-ape::root(arbolUPGMA, outgroup = "HUMANO", r=TRUE)
arbolUPGMAraiz plot(arbolUPGMAraiz)
Además podemos visualizar los dos árboles al tiempo con los siguientes comandos:
layout(matrix(c(1,2)), height=c(10,10))
par(mar=c(1,1,1,1))
plot(arbolUPGMAraiz, label.offset=0.0005, main="ARBOL UPGMA", cex=0.4)
plot(arbolNJraiz, label.offset=0.0005, main="ARBOL NJ", cex=0.4)
La parsimonia busca disminuir el número de pasos que explican un árbol evolutivo contando el número de cambios de cada uno de los caracteres. En los métodos de distancia (UPGMA y NJ) sólo se llega a un único árbol, mientras que en parsimonia se evalúan múltiples árboles. Se suman todos los pasos reqerridos para explicar un árbol obteniendo un número que se compara entre otros árboles con diferentes pasos. El árbol con menor número de cambios es el ideal.
Hay que tener en cuenta que la parsimonia no usa todos los caracteres. Son eliminados aquellos que son constantes en todos los taxones, como los caracteres 1, 6 y 8 en la matrix de abajo; o aquellos que son varaibles pero no informativos, como 2, 3 y 4. Un caracter es informativo si tiene al menos dos estados de caracter y por lo menos dos estos estados ocurren co una frecuencia mínima de dos.
Taxa / Caracter | 1 | 2 | 2 | 5 | 5 | 6 | 6 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
A | A | A | G | A | G | T | G | C | A |
B | A | G | C | C | G | T | G | C | G |
C | A | G | A | T | A | T | C | C | A |
D | A | G | A | G | A | T | C | C | G |
Para estimar árboles de máxima parsiomonia existen varias posbilidades, la más sencilla es partir de árboles de distancia. Se utiliza un árbol de inicio obtenido por distancia y se cuenta su número de pasos. Podemos estimar, por ejemplo, el número de pasos del árbol arbolUPGMAraiz
.
::parsimony(arbolUPGMAraiz, influenza) phangorn
## [1] 349
El árbol arbolUPGMAraiz
tiene 349 pasos, algo importante es que aunque esté con raíz o no el número de pasos debe ser el mismo. Probémoslo usando el árbol sin raíz:
::parsimony(arbolUPGMA, influenza) phangorn
## [1] 349
Con el método optim.parsimony
se obtienen el árbol con mejor parsimonia. Este método permite encontrar árboles bajo máxima parsimonia usando árboles de distancia de inicio.
= phangorn::optim.parsimony(arbolUPGMAraiz, influenza) mejorUPGMA
## Final p-score 324 after 4 nni operations
Ahora hagámoslo con el árbol de NJ:
= phangorn::optim.parsimony(arbolNJraiz, influenza) mejorNJ
## Final p-score 324 after 0 nni operations
Hacer parsimonia con un número de taxones muy alto se convierte en una labor computacional ardua. Más allá de 10 taxones hay un número de combinaciones difíciles de obtener computacionalmente y se deben hacer búsquedas heurísticas, esto significa que no se evalúan todas las posibilidades de árboles.
Los métodos heurísticos buscan algunos árboles seleccionando un árbol inicial y cortando ramas y poniéndolas en otro lugar del árbol (branch swapping). Se puede interpretar como una muestra representativa de una problación para hacer inferencias a partir de ella. Hay varias formas de búsquedas heurísticas como:
Intercambio de vecino más cercano (Nearest Neighbor Interchange, NNI): Consiste en intercambir ramas adyacentes hacia una rama interna.
Podado de subárbol y reinjerto (Subtree pruning and regrafting, SPR): Se corta un pedazo de rama y se inserta en otra rama de manera azarosa.
Bisección de árbol y reconexión (Tree bisection and reconnection, TBR): Se corta el árbol en la mitad y una porción del árbol que queda de coloca en alguna parte que queda de las ramas del otro árbol.
Los anteriores métodos heurísticos son lentos computacionalente, a veces si crear cientos o miles de árboles con una parsimonia idéntica. Usalmente se debe, entonces, poner una restricción de búsqueda, por ejemplo un límite de árboles con los que trabajar.
Otra estrategia para hacer el proceso de búsqueda de árbol con mayor parsimonia es con el algoritmo de búsqueda pratchet. La cual tiene los siguientes pasos:
El algoritmo anterior es computacionalmente más amigable y rápido. Probémoslo usando la función pratchet
:
= phangorn::pratchet(influenza, all = TRUE) virus_parsimonia
Se genera un árbol, se pesan caracteres por defecto y se itera un número determiando de veces. El algoritmo ha encontrado múltiples ocasiones que el árbol más corto es de 324 pasos ero sólo 4 árboles con igual longitud y número de pasos aunque presenten diferente topología.
virus_parsimonia
## 4 phylogenetic trees
Para poderlos comparar es necesario enraizarlos. en este caso los enreizamos con el virus de la influenza del humano, de que sabemos que debe de estar menos emparentado con los virus de las aves.
= ape::root(phy = virus_parsimonia, outgroup = "HUMANO")
virus_parsimoniaR plot(virus_parsimoniaR, cex = 0.6)
Para escoger el sólo un árbol con igual parsimonia hay que un árbol de consenso. Una posibilidad es un árbol de consenso estricto, sólo los grupos monofiléticos presentes en todos los árboles son incluidos; si un grupo monofilétco no está presente en todos los árboles colapsa formando una politomía en el árbol consenso. Este tipo de consenso es muy riguroso y suele tener muchas politomías, de modo que se puede hacer un consenso con una regla de mayoría. Por ejemplo, si un grupo está presente en una mayoría del 51% de árboles, entonces el árbol consenso lo incluye, si sólo está presente en el 50%, el consenso no lo usa.
Para hacer un árbol de consenso estricto podemos usar el método ape
con parámetro p
de 1:
= ape::consensus(virus_parsimoniaR, p = 1)
estrictode100 plot(estrictode100, cex = 0.6)
Para un árbol menos estricto podemos cambiar el valor del parámetro p
:
= ape::consensus(virus_parsimoniaR, p = 0.5)
estricto50 plot(estricto50, cex = .6)
El resultado es un árbol con menos politomías, más resuelto.
Para dar soporte a los árboles se puede hacer una serie de seudoréplicas con remplazamiento (bootstrapping) de una matriz. Los cambios entre seudoréplicas consisten en el uso diferencial de los caracteres. Se crean árboles en los que un mismo caracter se repite u otro no se usa.
Por ejemplo, si la matriz original es la siguiente, con los caracteres 1, 2, 3, 4, 5, 6, 7 y 8:
Taxa / Caracter | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|
A | A | A | G | C | C | T | A | G |
B | A | G | C | C | T | A | G | C |
C | G | C | C | T | G | A | C | T |
D | G | G | T | C | T | A | G | C |
Outgroup | G | T | C | G | T | T | A | C |
Una posible seudoréplica es una en la que se usen sólo los caracteres 1, 2, 5, 6, y 8 repiéndolos de modo que hay la misma dimensión de la matriz original.
Taxa / Caracter | 1 | 2 | 2 | 5 | 5 | 6 | 6 | 8 |
---|---|---|---|---|---|---|---|---|
A | A | A | A | C | C | T | T | G |
B | A | G | G | T | T | A | A | C |
C | G | C | C | G | G | A | A | T |
D | G | G | G | T | T | A | A | C |
Outgroup | G | T | T | T | T | T | T | C |
Con cada réplica se hace un árbol consenso; la veces que un grupo se repita en el conjunto de réplica es el valor de soporte del nodo. Esta técnica, ampliamente utilizada, proporciona evaluaciones de «confianza» para cada clado de un árbol observado, basándose en la proporción de árboles bootstrap que muestran ese mismo clado. Normalmente un nodo con un soporte mayor a 80% es un buen soporte.
= phangorn::bootstrap.phyDat(influenza, FUN = pratchet, bs = 10) arbolesbootstrap
En este caso usamos la función pratchet
, si usáramos otra se demoraría más. También usamos un número de réplicas irrisosio pues este es un ejercicio demostrativo y no es necesrio gatar mucho tiempo en él. La rutina anterior genera entonces 10 árboles seudoréplicas.
plot(arbolesbootstrap, cex = .6)
Ahora bien, generamos un consenso; en este caso con un consenso al 60%:
= ape::consensus(arbolesbootstrap, p = 0.6)
estricto100 plot(estricto100, cex = .6)
Lo cual genera un árbol con bastante parafilia.
Métodos de reconstrucción filogenética basados en modelos probabilísticos. Los caracteres en este caso no son sólo caracteres si no que también representn dinámicas evolutivas. A diferencia de la parsimonia, con estos modelos todos los caracteres son útiles, ncluso los que son constantes entre todos los taxones. Además estos cumplen con un modelo evolutivo.
Se calcula la verosimilitud (probabilidad de obtener un dato según un modelo) de un árbol de acuerdo a un alineamiento de secuencias usando un modelo de evolución de nucleótidos. Este modelo se presenta como una matriz de substitución que muestra las probabilidades de cambio entre los cuatro nucleótidos (por lo tanto esta matriz será 4x4). También se tienen en cuenta la frecuencia de de ocurrencia de las bases. Los pasos para determinar la verosimilitud de un árbol son:
Por nodo, se consideran todos los escenario posibles que pudieron dar origen a los estados de caracter observados para dicho sitio. La verosimilitud de un sitio es, entonces, la suma de verosimilitudes de la reconstrución de este sitio (en forma de árbol) dado un modelo de evolución o sustitución —los cuales se mencionana abajo—.
La verosimilitud total del árbol, \(L\), a diferencia del cálculo por sitio en que se suma, es el producto de las verosimilitudes por sitio.
\[ L = L_1 * L_2 * ... * L_n = \prod_{i = 1}^{n}L_i \] Al final, se suele trabajar con el logaritmo nepetiano de las verosimilitudes para hacer los valores más grandes y manejables:
\[
ln(L) = ln(L_1) * ln(L_2) * ... * ln(L_n) = \prod_{i = 1}^{n}ln(L_i)
\] Por lo anterior, la verosimilitud es computacionalmente costosa. Para el ejemplo usamos de nuevo nuestro objeto influenza
de clase phy
y creamos un árbol al azar de 21 ramas con rtree
como punto de partida.
= ape::rtree(n = 21, tip.label = names(influenza))
arbolazar plot(arbolazar, cex = .5)
En seguida lo enraizamos por el virus de la influenza humana para poderlo visualizar mejor. Además los «escalerizamos» hacia la derecha y le agregamos escala; aquí la longitud de la rama sí es significativa, indica cantidad de cambio en cuanto a sustituciones nucleotídicas (pues se usan nucleótidos en el alineamiento múltiple de las secuencias, chars2.txt
).
= ape::root(phy = arbolazar, outgroup = "HUMANO")
arbolazarR plot(ladderize(arbolazarR), cex = .5); add.scale.bar()
A partir del arbol de arriba se peude iniciar la búsqueda del mejor árbol por máxima verosimilitud. Lo primero que se hace es carcular la verosimilitud del árbol dadas las secuencias. Con pml
(Phylogenetic maximum likelihood), podemos computar tal verosimilitud.
= phangorn::pml(arbolazarR, influenza)
ajustado ajustado
##
## loglikelihood: -32234.36
##
## unconstrained loglikelihood: -5180.792
##
## Rate matrix:
## a c g t
## a 0 1 1 1
## c 1 0 1 1
## g 1 1 0 1
## t 1 1 1 0
##
## Base frequencies:
## 0.25 0.25 0.25 0.25
La información que tiene el objeto ajustado
nos reporta la verosimilitud del árbol al azar que habíamos creado, que es -5180.792. También reporta un modeo de substitución general, el cual tal vez no se ajuste bien a los datos. Lo que hay que hacer es encontrar un árbol que optimice la verosimilitud usando un modelo de sustitución; para esto vamos a usar el método phangorn::optim.pml
, el cual computa la verosimilitud de un árbol filogenético dado un alineamiento múltiple de secuencias y un modelo de evolución de DNA. Toma como argumentos un objeto de clase pml
, el tipo de modelo que se queire usar así como el tiempo de rearreglo para los árboles.
= phangorn::optim.pml(object = ajustado, model = "GTR", rearrangement = "ratchet") ajustadoconGTR
Para ver el árbol oculto usamos $tree
. También lo enraizamos.
$tree
ajustadoconGTR= ape::root(ajustadoconGTR$tree, outgroup = "HUMANO")
ajustadoconGTRraíz plot(ladderize(ajustadoconGTRraíz), cex = .5); add.scale.bar()
El árbol anterior fue generado por el modelo evolutivo GTR. Pero se pueden usar diferentes modelos. Por ejemplo, con HKY y F81.
= phangorn::optim.pml(object = ajustado, model = "JC", rearrangement = "ratchet")
ajustadoconJC = phangorn::optim.pml(object = ajustado, model = "HKY", rearrangement = "ratchet")
ajustadoconHKY = phangorn::optim.pml(object = ajustado, model = "F81", rearrangement = "ratchet") ajustadoconF81
Representaciones del proceso de evolución. Tienen en cuenta la frecuencia de los nucléotidos y la tasa de transición o transversión. Usualmente son más comunes las transiciones porque suelen producir mutaciones sinónimas, lo cual hace que no sean tan sensibles a la selección. También se tiene en cuenta en estos modelos es la heterogeneidad de las secuencias (\(G\)), esto es una medida para la variabilidad de las bases. Otro aspecto relevante en los modelos de sustitución o de evolución son los mismos árboles filogenéticos, de los que se tiene en cuenta las longitud de las ramas y su topología.
El modelo más sencillo es el de Jukes-Cantor, según el cual la frecuencia de las bases en idéntica y las tasas de substitución tampoco varían. Por ello, sólo cuenta con un prámetro, \(\lambda\).
\[ Q = \begin{pmatrix} * & \lambda & \lambda \\ \lambda & * & \lambda \\ \lambda & \lambda & * \end{pmatrix} \]
Por otro lado, mientras Kimura 2 tiene los supuestos de que hay igual frecuencia de bases y que las tasas de substitución son diferentes, F81 supone iguales tasas de sustitución pero diferentes frecuencuencias de bases. Normalmente, a mayor número de parámetros, mayor complejidad.
Hay muchos otros modelos. Se precisa, etnocnes, decidir cuál modelo se ajusta mejor con los datos de trabajo en un filogenía por máxima verosimilitud. Sin embargo, se ha demostrado que el modelo de sustitucion usado no tiene mucho efecto en la filogenia resultante.
Existen programas para el modelo de sustitución que mejor se ajusta a los datos, entre estos están Jmodeltest
, PAUP
. Para determinar el mejor modelo se compra la verosimilutd de un conjunto de dados usando diferentes modelos, esto mdiante pruebas dde hipóteisis (Likelihood Ratio Test, LRT). El modelo con mejor verosimilitud (valor más bajo, \(L\)) es el que mejor se ajusta a los datos.
«Esencialmente, todos los modelos están mal, pero algunos son útiles» —George E. P. Box
En R
una manera de comparar los diferentes modelos es mediante phangorn::AIC
.
AIC(ajustadoconGTR, ajustadoconJC, ajustadoconHKY, ajustadoconF81)
## df AIC
## ajustadoconGTR 47 8869.358
## ajustadoconJC 39 9284.922
## ajustadoconHKY 43 8870.705
## ajustadoconF81 42 9182.652
La primera columna corresponde a los grados libertad. Según el criterio anterior, el mejor modelo que se ajusta con los datos es GTR (con el AIC más bajo) y optimiza la verosimilitud. Pero para evaluar más modelos, podemos usar modelTest
de phangorn
, el cual necesita un árbol de inicio.
= phangorn::modelTest(influenza, ajustadoconGTRraíz) influenzaModelTest
## [1] "JC+I"
## [1] "JC+G"
## [1] "JC+G+I"
## [1] "F81+I"
## [1] "F81+G"
## [1] "F81+G+I"
## [1] "K80+I"
## [1] "K80+G"
## [1] "K80+G+I"
## [1] "HKY+I"
## [1] "HKY+G"
## [1] "HKY+G+I"
## [1] "SYM+I"
## [1] "SYM+G"
## [1] "SYM+G+I"
## [1] "GTR+I"
## [1] "GTR+G"
## [1] "GTR+G+I"
influenzaModelTest
## Model df logLik AIC AICw AICc AICcw BIC
## 1 JC 39 -4603.461 9284.922 1.480290e-112 9286.804 2.280895e-112 9496.973
## 2 JC+I 40 -4555.867 9191.733 2.547111e-92 9193.713 3.737592e-92 9409.222
## 3 JC+G 40 -4554.713 9189.425 8.077474e-92 9191.405 1.185276e-91 9406.913
## 4 JC+G+I 41 -4553.518 9189.036 9.812024e-92 9191.116 1.369425e-91 9411.962
## 5 F81 42 -4549.326 9182.652 2.388330e-90 9184.834 3.166345e-90 9411.014
## 6 F81+I 43 -4501.910 9089.819 3.438913e-70 9092.107 4.325312e-70 9323.619
## 7 F81+G 43 -4500.739 9087.478 1.108578e-69 9089.766 1.394320e-69 9321.278
## 8 F81+G+I 44 -4499.574 9087.148 1.307396e-69 9089.544 1.558054e-69 9326.385
## 9 K80 40 -4444.749 8969.498 4.612162e-44 8971.477 6.767818e-44 9186.986
## 10 K80+I 41 -4395.506 8873.013 4.124354e-23 8875.092 5.756196e-23 9095.938
## 11 K80+G 41 -4394.356 8870.712 1.302867e-22 8872.792 1.818359e-22 9093.638
## 12 K80+G+I 42 -4392.978 8869.957 1.900660e-22 8872.139 2.519814e-22 9098.320
## 13 HKY 43 -4392.352 8870.705 1.307864e-22 8872.992 1.644973e-22 9104.504
## 14 HKY+I 44 -4344.060 8776.121 4.520840e-02 8778.516 5.387589e-02 9015.358
## 15 HKY+G 44 -4342.978 8773.955 1.334790e-01 8776.351 1.590700e-01 9013.192
## 16 HKY+G+I 45 -4341.876 8773.752 1.477445e-01 8776.258 1.666140e-01 9018.426
## 17 SYM 44 -4439.958 8967.917 1.016726e-43 8970.312 1.211656e-43 9207.154
## 18 SYM+I 45 -4390.044 8870.088 1.779809e-22 8872.594 2.007122e-22 9114.763
## 19 SYM+G 45 -4388.867 8867.735 5.773291e-22 8870.241 6.510642e-22 9112.409
## 20 SYM+G+I 46 -4387.367 8866.734 9.524618e-22 8869.353 1.015121e-21 9116.845
## 21 GTR 47 -4387.679 8869.358 2.564353e-22 8872.093 2.579655e-22 9124.907
## 22 GTR+I 48 -4339.464 8774.929 8.203164e-02 8777.782 7.778965e-02 9035.915
## 23 GTR+G 48 -4338.303 8772.607 2.619839e-01 8775.459 2.484363e-01 9033.593
## 24 GTR+G+I 49 -4337.074 8772.148 3.295527e-01 8775.121 2.942142e-01 9038.571
El modelo que mejor se ajusta, según ModelTest
es GTR+G+I, el cual tienen en cuanta la heterogneidad. Una vez se sabe el mejor modelo, se puede buscar el mejor árbol, pero como el modelo GTR+G+I no existe como opción hay que expecificarlo con condiciones. De modo que incluya los sitios invariantes y tenga en cuenta la heterogeneidad.
= phangorn::optim.pml(
mejorarbol object = ajustadoconGTR,
model = "GTR",
optInv = TRUE,
optGamma = TRUE,
rearrangement = "ratchet")
## only one rate class, ignored optGamma
## optimize edge weights: -4387.679 --> -4387.679
## optimize base frequencies: -4387.679 --> -4387.679
## optimize rate matrix: -4387.679 --> -4387.679
## optimize invariant sites: -4387.679 --> -4339.704
## optimize edge weights: -4339.704 --> -4339.55
## optimize topology: -4339.55 --> -4339.55
## 0
## [1] "Ratchet iteration 1 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 2 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 3 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 4 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 5 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 6 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 7 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 8 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 9 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 10 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 11 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 12 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 13 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 14 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 15 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 16 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 17 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 18 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 19 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 20 , best pscore\n so far: -4339.4835468905"
## [1] "Ratchet iteration 21 , best pscore\n so far: -4339.4835468905"
## optimize base frequencies: -4339.484 --> -4339.467
## optimize rate matrix: -4339.467 --> -4339.39
## optimize invariant sites: -4339.39 --> -4339.389
## optimize edge weights: -4339.389 --> -4339.389
## optimize topology: -4339.389 --> -4339.389
## 0
## optimize base frequencies: -4339.389 --> -4339.386
## optimize rate matrix: -4339.386 --> -4339.386
## optimize invariant sites: -4339.386 --> -4339.386
## optimize edge weights: -4339.386 --> -4339.386
## optimize base frequencies: -4339.386 --> -4339.386
## optimize rate matrix: -4339.386 --> -4339.386
## optimize invariant sites: -4339.386 --> -4339.386
## optimize edge weights: -4339.386 --> -4339.386
mejorarbol
##
## loglikelihood: -4339.386
##
## unconstrained loglikelihood: -5180.792
## Proportion of invariant sites: 0.6974688
##
## Rate matrix:
## a c g t
## a 0.0000000 1.055574 6.89374 0.8678635
## c 1.0555742 0.000000 0.29449 8.9680753
## g 6.8937398 0.294490 0.00000 1.0000000
## t 0.8678635 8.968075 1.00000 0.0000000
##
## Base frequencies:
## 0.346711 0.1844641 0.2266299 0.242195
La verosimilitud ahora es de -4339.386, también se reporta que el 70% de las secuencias son regioes invariantes. Ahora veamos el árbol.
= ape::root(mejorarbol$tree, outgroup = "HUMANO")
mejorarbolR plot(ladderize(mejorarbolR), cex = 0.5); add.scale.bar()
Este sería nuestro mejor mejor árbol bajo el modelo de máxima verosimilitud.
Para esto no usamos R.