---
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 árboles). Segundo, la matriz de caracteres tiene que estár 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 árboles). 

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`. Al igual que con los brackets dobles, el resultado de la función `extractVector` es un vector con nombres.


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

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

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

Hay un par de aspectos que son únicos a `[[.treedata.table()` y `extractVector()`. Primero, `[[.treedata.table()` tiene un argumento adicional que permite un correspondencia parcial del nombre de la columna (i.e. cuando el nombre objetivo tiene una superposicion parcial con los elementos en el objeto). Segundo, `extractVector()` puede extraer múltiples columnas y permite una evaluación no estandard (i.e. los nombres son tratados como cadenas de texto literal).


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 operadas usando la misma sintaxis de `data.table`. En el siguiente ejemplo, los árboles 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 simultánea crear una nueva columna y reducir el número de taxones en la filogenia a las especies de interés.

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

`treedata.table` permite aplicar funciones directamente en nuestros datos de interés. 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 terminales 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 último, el árbol y la matriz de caracteres pueden ser extraídos 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`.
