Skip to content

Taller IFIBYNE (M3.B)

Lo que sigue es el .rmd de la guía.

---
title: "\[ATR\] Taller IFIBYNE (M3.B)" author: "Nicolás Méndez" date: "2019/8/13" output:
    pdf_document:
      toc: true
      toc_depth: 3
      number_sections: true
urlcolor: blue 
---

Tip del módulo: Alt + Shift + K (atajo para ver todos los atajos).

# Opciones globales knitr::opts_chunk\$set(echo = TRUE) knitr::opts_chunk\$set(out.width='90%', dpi=300) knitr::opts_chunk\$set(fig.align='center', dev = "png") options(max.print=50) library("gridExtra") library("reshape2")

Aprender a caminar corriendo (½)

Como la sintaxis se repite en todos los gráficos, la idea es tomar la "anatomía" de ggplot como referencia y hacer cualquier gráfico.

Los organizamos en varias categorías: 1D, 2D, 3D y otras.

Good luck!

Preparar entorno

  1. Cargar la librería de ggplot. 2. Usar el dataset "iris".

    iris es otro dataset de ejemplo: una tabla de mediciones del ancho y largo de sépalos y pétalos en diferentes especies.

```{r cars, message=FALSE} library(tidyverse) # Incluye ggplot2

Usaremos datos de ejemplo en head(iris) ```

Flashback

  • ¿Qué columnas tiene el data frame iris?

  • ¿Qué tipo de datos contiene cada columna?

    ¿Cuales son contínuas? ¿Alguna debería considerarse discreta o categórica?

  • Resumir las variables agrupando por Species usando la media:

    En base R es: aggregate(. ~ Species, iris, FUN = mean) %>% melt()

    O en tidycosas:

```{r} # A veces no es más elegante iris_tidy_summary <- iris %>%

gather(key = "attribute", value = "measurement", -Species) %>%
group_by(Species, attribute) %>%
summarise(media = mean(measurement),
          varianza = var(measurement))
```{r, include = F} iris_means <- aggregate(. \~ Species, iris, FUN = mean) %>% melt(id.vars = "Species") iris_melt <- melt(iris, id.vars = "Species") ```

## Gráficos 1D

A continuación, una serie de ejemplos de cada tipo de gráfico "1D". Usen la geometría indicada para reproducir el gráfico en sus computadoras.

Recuerden que para usar una tabla de datos en ggplot, esta debe convertise al formato "largo".

### geom_hist() y geom_density()

```{r, eval = F} ggplot(data = ? , aes( ? )) +

    geom_histogram( ? )
  1. Hacer los histogramas del valor de la medición, para cada atributo.

    Por defecto geom_hist usa position = "stack".

    Eso significa que, para cada bin, la altura de la barra es el numero global de ocurrencias del bin.

    Esa altura es la suma del número de ocurrencias de cada grupo en ese bin. La contribución de cada grupo se vuelve evidente coloreando algun aes por fill.

```{r, echo = F, message=F} iris_melt <- melt(iris, id.vars = "Species")

p3 <- ggplot(iris_melt, aes(value)) +

geom_histogram() +  # Valor por defecto
theme_minimal()

p4 <- ggplot(iris_melt, aes(value, fill = variable)) +

geom_histogram() +  # Valor por defecto
theme_minimal() + theme(legend.position = "none")

grid.arrange(p3, p4, ncol = 1) ```

Sirve para ver la distribución global de la variable, y la contribución de cada grupo al total del bin.

Prueben usar position = "fill" en geom_histogram().

¿Qué nos convendría si quisieramos comparar distribuciones por grupo?

  1. Explorar las opciones para el argumento position de geom_hist():

    • position = "stack" (valor por defecto, las counts de un bin se apilan)
    • position = "identity"
    • position = "fill"
    • position = "dodge"
    • position = "nudge"

```{r, echo = F, message = F} ggplot(iris_melt, aes(value, fill = variable)) +

geom_histogram(alpha = .5, position = "identity") +  # Valor por defecto
theme_minimal()
3. Finalmente, llega `geom_density()`.

     Esta geometría genera una PDF a nuestros datos.

     Su sintaxis es similar a la de `geom_hist()`.

     En el gráfico a continuación, hice mapping con `fill` (igual que antes) y agregué `linetype`.

```{r, eval = F} ggplot(data = ? , aes( ? )) +

    geom_density( ? )

```{r, echo = F, message = F} ggplot(iris_melt, aes(value, fill = variable, linetype = variable)) +

geom_density(alpha = .5, position = "identity") +  # Valor por defecto
theme_minimal()
Se puede usar `aes(y=..density..)` en el histograma anterior, para superponerlo con un density plot y comprararlos.

### geom_col() y geom_bar()

1. Hacer los gráficos de barra de la media por especie, para cada atributo.

     Por defecto, `geom_bar` usa `stat_count` (la cuenta de eventos por grupo) y `geom_col()` usa `stat_identity` (no hace ninguna transformación).

     Estas geometrías no calculan la media, así que debemos hacerlo nosotros:

     * Opción 1: calcular las medias de antemano con `arrange` o `summarise` y graficarlas.

     * Opción 2: usar lo que aprendimos antes: `geom_bar(stat = "summary", fun.y = "mean")` o `stat_summary`.

2. ¿Es esta la mejor visualización para nuestros datos?

     Podemos usar una geometría que calcule la media, como `geom_boxplot`, que incluye más estadísticos.

     <!-- ¿Hay otras? -->

```{r, out.width = '95%', fig.width=10, fig.height=5, echo = F} dodge <- position_dodge(width = 0.9)

p1 <- ggplot(iris_tidy_summary, aes(x = Species, y = media, fill = attribute)) +

    geom_col(position = dodge) +
    # geom_errorbar(
    #   aes(ymin = varianza + media, ymax = media - varianza),
    #   position = dodge,
    #   width = 0.2
    # ) +
    theme_minimal() + ylab("Mean value (cm)")

p2 <- ggplot(iris_tidy_summary, aes(x = attribute, y = media, fill = Species)) +

    geom_col(position = dodge) +
    # geom_errorbar(
    #   aes(ymin = varianza + media, ymax = media - varianza),
    #   position = dodge,
    #   width = 0.2
    # ) +
    theme_minimal() + ylab("Mean value (cm)")

grid.arrange(p1, p2, ncol = 2)

geom_boxplot() y geom_violin()

Estructura:

```{r, eval = F} ggplot(data = ? , aes( ? )) +

geom_boxplot( ? )
1. Hacer "boxplot" de `iris` por especie, para un atributo.

     Quizás quieran intentar cambiar el ancho de las cajitas pasando `width = .5` a `geom_boxplot()`.

     ¿Qué información contiene un boxplot?

     ¿Es necesario hacer `melt(iris)` en este caso?

```{r, echo = F, message = F, out.width = '40%', fig.width=3, fig.height=3} ggplot(iris, aes(x = Species, y = Sepal.Length)) +

    geom_boxplot(width = .5)

``` 2. Hacer un "violin plot" con lo mismo.

     Este tipo de gráfico es un "density plot", girado 90° y espejado.

     La idea es comparar distribuciones, al igual que en el density plot que hicimos arriba.

```{r, echo = F, message = F, out.width = '40%', fig.width=3, fig.height=3} ggplot(iris, aes(x = Species, y = Sepal.Length)) +

    geom_violin(width = .5, draw_quantiles = 0.5)
  1. Agregar una capa al gráfico anterior, para incluir los puntos graficados sobre el violin plot.

    Luego en vez de usar geom_point(), prueben con geom_jitter(size = .5, width = .1).

    Usamos los parámetros size y width para tener puntos más pequeños y no tan "jittereados", respectivamente.

```{r, echo = F, message = F, out.width = '40%', fig.width=3, fig.height=3} ggplot(iris, aes(x = Species, y = Sepal.Length)) +

geom_violin(width = .5, draw_quantiles = 0.5) +
geom_jitter(aes(color = Sepal.Length), width = .1, size = .5) +
theme_minimal() + theme(legend.position = "none") + scale_color_viridis_c()
4. Noten que el origen del eje vertical no empieza en cero.

     ¿Está bien o está mal?

     Pueden cambiar los límites con `ylim()` o `xlim()`.



```{r, echo = F, message = F, out.width = '40%', fig.width=3, fig.height=3} ggplot(iris, aes(x = Species, y = Sepal.Length)) +

    geom_violin(width = .5, draw_quantiles = 0.5) +
    geom_jitter(aes(color = Sepal.Length), width = .1, size = .5) +
    theme_minimal() + theme(legend.position = "none") + scale_color_viridis_c() + ylim(0, NA)

Bonus: argumento de posición

```{r, out.width = '95%', fig.width=8, fig.height=6} p3 <- ggplot(melt(iris)) +

geom_boxplot(aes(variable, value, color = Species), position = "dodge") +
ylim(0, NA) + theme(legend.position = "top")

p4 <- ggplot(melt(iris)) +

geom_boxplot(aes(variable, value, color = Species), position = position_dodge(width=0.2)) +
ylim(0, NA) + theme(legend.position = "top")

grid.arrange(p3, p4, ncol = 2) ```