---
title: "Breve Introducción al Paquete treedata.table"
author: "Cristian Roman-Palacios, April Wright, Josef Uyeda"
date: "09/06/2020"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Breve Introducción al Paquete treedata.table}
  %\VignetteEngine{knitr::rmarkdown}
  \usepackage[utf8]{inputenc}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Breve Introducción al Paquete `treedata.table`

El paquete `treedata.table` tiene como objetivo permitir a investigadores acceder y manipular datos filogenéticos usando herramientas del paquete `data.table`. `data.table` tiene diferentes funciones para manipular rápidamente datos en una forma eficiente.

El primer paso para usar `treedata.table` consiste en crear un objeto `treedata.table`. El objeto `treedata.table` empareja los tip.labels de la filogenia con una columna en el `data.frame` que contiene los nombres de los taxones. Este paso inicial permite la manipulación subsecuente y coordinada de los datos en el árbol y la matriz de caracteres dentro de `treedata.table`.

Para este tutorial vamos a usar los datos de Anolis creados en `treeplyr`. Estos caracteres fueron generados aleatoriamente. Es importante resaltar tres aspectos. Primero, el árbol tiene que ser en formato `phylo` (o `multiPhylo` en caso de múltiples arboles). Segundo, la matriz de caracteres tiene que están en formato `data.frame`. Tercero, la matriz de caracteres tiene que contener una columna con los nombres de los taxones coincidiendo con los tip.labels del árbol (o arboles). 

El objeto `treedata.table` se crea usando la función `as.treedata.table`.

```{r}
library(ape)
library(treedata.table)

# Cargamos los datos del ejemplo
data(anolis)
# Creamos el objecto treedata.table con as.treedata.table
td <- as.treedata.table(tree = anolis$phy, data = anolis$dat)
```

Podemos revisar el objeto resultante simplemente llamando el nombre del objeto en la consola. La matriz de caracteres, antes en `data.frame`, es ahora un `data.table`

```{r}
td
```

Adicionalmente, la matriz de caracteres en el nuevo formato `data.table` ha sido re-ordenado para tener las filas en el mismo orden que los tip.labels en el árbol.


```{r}
td$phy$tip.label == td$dat$tip.label
```


## Manipulando Datos

La matriz de datos en el objeto treedata.table puede ser indexada como cualquier otro objeto `data.table`. Por ejemplo, podemos hacer lo siguiente para extraer la columna con información de longitud hocico-cloaca (SVL) para cada especie.

```{r pressure, echo=TRUE}
td$dat[,'SVL']

```

También podemos usar los brackets dobles para extraer directamente la misma columna como un vector con nombres.

```{r}
td[["SVL"]]
```

El mismo resultado puede también ser logrado usando la función `extractVector`. El producto de `extractVector` como los brackets dobles es un vector con nombres.


```{r}
extractVector(td, 'SVL')
```

Múltiples columnas pueden tambien ser extraídas usando `extractVector`.

```{r}
extractVector(td, 'SVL','ecomorph')
```

Sin embargo, hay un par de aspectos que son únicos a `[[.treedata.table()` y `extractVector()`. Primero, `[[.treedata.table()` tiene un argumento adicional que permite un match parcial del nombre de la columna. Segundo, `extractVector()` puede extraer múltiples columna y permite una evaluación no standard.


El poder real de `treedata.table` está en coindexar el árbol con la matriz de caracteres. Por ejemplo, en el siguiente comando usamos la sintaxis de `data.table` para extraer el primer representante de cada ecomorfo y retener todas las columnas. 

```{r}
 td[, head(.SD, 1), by = "ecomorph"]

```

Podemos hacer la misma operación con múltiples columnas.

```{r}
td[, head(.SD, 1), by = .(ecomorph, island)]

```

También implementamos la función `tail`.

```{r}
 td[, tail(.SD, 1), by = "ecomorph"]

```

Las columnas en `treedata.table` pueden ser también operadas usando sintaxis en `data.table`. En el siguiente ejemplo, los arboles solo incluirán especies distribuidas en Cuba. Este es el equivalente a filtrar usando `dplyr`. Después, una nueva columna llamada “Index” es creada en el objeto `data.table` dentro del objeto `treedata.table` con los valores de SVL+hostility. En resumen, la siguiente línea permite en forma simultanea crear una nueva columna y resumir el numero de taxones en la filogenia a las especies de interés.

```{r}
td[island == "Cuba",.(Index=SVL+hostility)]
```

También podemos usar `treedata.table` para correr funciones en nuestros datos. En el siguiente ejemplo, evaluamos un modelo de evolución browniano sobre los datos de SVL en nuestro set de datos. Usamos una combinación de `tdt`, `extractVector` y `geiger::fitContinuous` para correr funciones en nuestros datos, extraer un vector de caracteres y ajustar el model en cuestión, respectivamente.

```{r}

tdt(td, geiger::fitContinuous(phy, extractVector(td, 'SVL'), model="BM", ncores=1))

```

Los tips en el árbol también pueden ser removidos fácilmente, con los cambios también reflejados sobre la matriz de caracteres. En el siguiente ejemplo, removemos dos taxones por sus nombres.


```{r}
dt <- droptreedata.table(tdObject=td, taxa=c("chamaeleonides" ,"eugenegrahami" ))
```

Revisamos si *A. chamaeleonides* y *A. eugenegrahami* aún están en el árbol.

```{r}
c("chamaeleonides" ,"eugenegrahami" ) %in% dt$phy$tip.label
```

Y podemos hacer lo mismo con la matriz de caracteres en el nuevo objeto `treedata.table`.

```{r}
c("chamaeleonides" ,"eugenegrahami" ) %in% dt$dat$X
```

Por ultimo, el arbol y la matriz de caracteres pueden ser extraidos de el objeto `treedata.table` fácilmente usando la función ` pulltreedata.table`. 

```{r}
df <- pulltreedata.table(td, "dat")
tree <- pulltreedata.table(td, "phy")
```

La tabla

```{r}
df
```

Y el árbol

```{r}
tree
```

La misma funcionalidad explicada en este tutorial sobre objetos `phylo` aplica directamente a objetos `multiPhylo`.
