Datos y paquetes

Como siempre, el primer paso es cargar los datos y paquetes que vamos a necesitar. Los datos corresponden a una base de datos de la esperanza de vida según la OMS y se pueden descargar aquí: https://www.kaggle.com/kumarajarshi/life-expectancy-who. Para simplificar el análisis, únicamente utilizaremos el año 2015.

Nota: si se utiliza iOS, es necesario instalar XQuarz https://www.xquartz.org. De no hacerlo, no se podrá usar la función ggplotly.

library(tidyverse)
library(ggplot2)
library(plotly)
library(Cairo)
library(forcats)

lifeexpectancy <- read.csv("/Users/luissandoval/Desktop/Personal_Data_Science_Projects/Life Expectancy Data.csv")
head(lifeexpectancy)
##       Country Year     Status Life.expectancy Adult.Mortality infant.deaths
## 1 Afghanistan 2015 Developing            65.0             263            62
## 2 Afghanistan 2014 Developing            59.9             271            64
## 3 Afghanistan 2013 Developing            59.9             268            66
## 4 Afghanistan 2012 Developing            59.5             272            69
## 5 Afghanistan 2011 Developing            59.2             275            71
## 6 Afghanistan 2010 Developing            58.8             279            74
##   Alcohol percentage.expenditure Hepatitis.B Measles  BMI under.five.deaths
## 1    0.01              71.279624          65    1154 19.1                83
## 2    0.01              73.523582          62     492 18.6                86
## 3    0.01              73.219243          64     430 18.1                89
## 4    0.01              78.184215          67    2787 17.6                93
## 5    0.01               7.097109          68    3013 17.2                97
## 6    0.01              79.679367          66    1989 16.7               102
##   Polio Total.expenditure Diphtheria HIV.AIDS       GDP Population
## 1     6              8.16         65      0.1 584.25921   33736494
## 2    58              8.18         62      0.1 612.69651     327582
## 3    62              8.13         64      0.1 631.74498   31731688
## 4    67              8.52         67      0.1 669.95900    3696958
## 5    68              7.87         68      0.1  63.53723    2978599
## 6    66              9.20         66      0.1 553.32894    2883167
##   thinness..1.19.years thinness.5.9.years Income.composition.of.resources
## 1                 17.2               17.3                           0.479
## 2                 17.5               17.5                           0.476
## 3                 17.7               17.7                           0.470
## 4                 17.9               18.0                           0.463
## 5                 18.2               18.2                           0.454
## 6                 18.4               18.4                           0.448
##   Schooling
## 1      10.1
## 2      10.0
## 3       9.9
## 4       9.8
## 5       9.5
## 6       9.2
life2015 <- lifeexpectancy %>% filter(Year == 2015)

De gráficos estáticos a interactivos

plotly nos permite convertir gráficos estáticos creados con ggplot2 a gráficos interactivos. El gráfico a continuación muestra la relación entre esperanza de vida y el índice de masa corporal (IMC).

exp_imc <- ggplot(life2015, aes(x = BMI, y = Life.expectancy)) +
  geom_point(alpha = 0.5)
exp_imc

Para convertirlo a un gráfico interactivo, únicamente pasamos el gráfico a la función de plotly. Mueva su mouse sobre la imagen para ver la interactividad del gráfico.

ggplotly(exp_imc)

Histogramas

Un histograma es la presentación gráfica de una variable continua. A continuación se muestra el código para crear un histograma de la variable Life.expectancy. A menos que se le indique lo contrario, el número de contenedores del gráfico será asignado automáticamente por el programa. En este caso se le indicó al programa que cree 15 contenedores. Adicionalmente, se le puede indicar donde inicia y terminan los contenedores y el tamaño de estos usando el código xbins = list(start = 0, end=100, size=10) adentro de add_histogram, como se muestra en el segundo gráfico.

life2015 %>%
    plot_ly(x = ~Life.expectancy) %>%
    add_histogram(nbinsx = 15)      

Adicionalmente, se le puede indicar donde inicia y terminan los contenedores y el tamaño de estos usando el código xbins = list(start = 0, end=100, size=10) adentro de add_histogram, como se muestra en el segundo gráfico.

life2015 %>%
    plot_ly(x = ~Life.expectancy) %>%
    add_histogram(xbins = list(start = 41, end=100, size=5))        

Gráfico de barras

Los gráficos de barras son utilizados para mostrar la distribución de frecuencia de variables categóricas. A continuación se muestra el gráfico de barras de la variable Status, que indica si el país es desarrollado o en vías de desarrollo. Primero se crea un cuadro con las frecuencias de la variable categórica y luego se usa ese cuadro para crear el gráfico. Finalmente, es prudente organizar las columnas en orden descendiente para facilidad del lector cuando se tienen muchas categorias. Para esto usamos la función fct_reorder del paquete forcats, como se muestra en el segundo gráfico. En este gráfico no se aprecia mucho porque únicamente tenemos dos categorías, pero esto hará una gran diferencia cuando se tienen más.

status_table <- life2015 %>%
    count(Status)   

status_table %>%
    plot_ly(x = ~Status, y = ~n) %>%
    add_bars()
status_table %>%
    mutate(Status = fct_reorder(Status, n, .desc = TRUE)) %>%
    plot_ly(x = ~Status, y = ~n) %>% 
    add_bars()  

Gráfico de barras apilado

También podemos hacer gráficos de barras apilados. En este caso, hemos creado una segunda variable categórica a partir del IMC (BMI) para utilizar en la demostración. La categorización se hizo a partir de los cuartiles de la variable. Nótese que la categorias adentro de las barras son seleccionables en la leyenda.

life2015$bmi.cat<-cut(life2015$BMI, c(2.50, 24.30, 48.60, 61.40, 77.60)) 

life2015 %>%
    count(Status, bmi.cat) %>%
    plot_ly(x = ~Status, y = ~n, color = ~bmi.cat) %>%
    add_bars() %>%
    layout(barmode = "stack")

Para hacer un gráfico de barra apilado que muestra la proporción, únicamente es necesario hacer una sencilla modificación al código según se muestra a continuación. La agrupación se hace según la variable categórica y luego usamos la función mutate para calcular la proporción.

life2015 %>%
    count(Status, bmi.cat) %>%
  group_by(Status) %>%
  mutate(prop = n/sum(n)) %>%
    plot_ly(x = ~Status, y = ~prop, color = ~bmi.cat) %>%
    add_bars() %>%
    layout(barmode = "stack")

Gráficos de caja

Los gráficos de caja se utilizan para mostrar la dispersión de variables continuas, utilizando los cuartiles de los datos para crear la caja. El gráfico a continuación muestra la distribución de la esperanza de vida según el status de los países.

life2015 %>% 
  plot_ly(x = ~Status, y = ~Life.expectancy) %>%
  add_boxplot()

Gráficos de dispersión

Los gráficos de dispersión muestra la relación entre dos variables continuas. El gráfico a continuación muestra la relación la esperanza de vida y los años de escolaridad de la población. Recuerda navegar sobre el gráfico y explorar las opción de interacción.

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy) %>%
  add_markers() 

Gráficos de punto

Los gráficos de punto muestran la relación entre una variable categórica y una variable cuantitativa. En este ejemplo, observaremos los 15 países con el IMC más alto (los más gorditos).

La función top_n selecciona las 15 observaciones de mayor valor según la variable que le indicamos. Luego, fct_reorder, se encarga de que el gráfico aparezca ordenado según esa variable.

life2015 %>%
  top_n(15, wt = BMI) %>%
  plot_ly(x = ~BMI, y = ~fct_reorder(Country, BMI)) %>%
  add_markers() %>%
  layout(xaxis = list(title = '´Indice de Masa Corporal (IMC)'), 
         yaxis = list(title = 'País', type = "category"))

También podemos agregar color a los gráficos de punto. En el ejemplo a continuación, se muestra los países escolaridad y su estatus.

life2015 %>%
  top_n(15, wt = Schooling) %>%
  plot_ly(x = ~Schooling, y = ~fct_reorder(Country, Schooling),
          color = ~fct_drop(Status),
          hoverinfo = "text",
          text = ~paste("Escolaridad:", Schooling, "<br>",
                        "PIB:", GDP, "<br>")) %>%
  add_markers(colors = c('blue', 'red')) 

Estilo

Color y transparencia

En algunas ocasiones será necesario cambiar el color del gráfico y hacerlo transparente para permitirle al lector ves la líneas guía del gráfico. En el cuadro a continuación, se muestra el histograma hecho anteriormente con el código que le cambia el color y lo hace transparente. En esta página podrá encontrar los colores nombrado que tiene R http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf.

life2015 %>%
    plot_ly(x = ~Life.expectancy) %>%
    add_histogram(color = I("red"), opacity = 0.5)      

Adicionamente, plotly permite utilizar colores a partir de RGB. El código a continuación muestra un color que debería de ser familiar para usted, el verde de Zamorano.

life2015 %>%
    plot_ly(x = ~Life.expectancy) %>%
    add_histogram(marker = list(color = "rgb(58,131,66)"))      

Tamaños y símbolos

En gráfico como los gráficos de dispersión, puede que sea de utilidad cambiar el tamaño y tipo de símbolo. A continuación se muestra el gráfico de dispersión que habiamos hecho pero con modificaciones al tamaño y tipo de símbolo.

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy) %>%
  add_markers(marker = list(size = 4, symbol = "diamond")) 

Uso del color

Utilizar colores en los gráficos no es únicamente una opción estética. Cuando usado correctamente, ayuda a la interpretación de los gráficos e incluso a incluir más variables en el mismo gráfico. En el gráfico de dispersión a continuación, se ha agregado la variable the status. Colors, en la función de add_markers, habré la posibilidad de utilizar colores diferentes a los default.

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy, color = ~Status) %>%
  add_markers(colors = "Dark2") 

En lugar de color, podemos utilizar símbolos también para agregar más variables a un gráfico de dispersión. En el gráfico a continuación se muestra las categorias (por cuartiles) del IMC.

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy, symbol = ~bmi.cat) %>%
  add_markers() 

Etiqueta

Habras notado que al posicionar el mouse sobre el gráfico, este muestra los valores de las observaciones. En plotly, esta opción se conoce como hooverinfo y muestra los valores de todas las variables por default. Se le puede indicar al programa que muestre los valores de únicamente variables seleccionadas e incluso que muestre los nombres de las variables. El uso de esta opción, deberá facilitar la lectura e interpretación del gráfico, no complicarla.

En el gráfico a continuación, únicamente se muestra el valor de la variable en el eje y, a pesar de tener dos variables adicionales.

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy, symbol = ~bmi.cat, hoverinfo = "y") %>%
  add_markers() 

Alternativamente, puede que no querramos que se muestren los valores, sino información adicional que nos permita identificar las observaciones. En el ejemplo a continuación, se agregó código para que al navegar sobre el gráfico se muestre que país es. ¿Puede encontrar su país?

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy, color = ~Status, hoverinfo = "text", text = ~Country) %>%
  add_markers() 

Ahora, por diversión, agreguemos texto a la información que muestra. En la opción de texto, primero indicamos el texto explicativo, como esperanza de vida, y luego la variable de donde se obtendrá dicha información.
se encargará de mostrar en líneas separadas la información.

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy, color = ~Status, hoverinfo = "text", text = ~paste("Esperanza de vida:", Life.expectancy, "<br>", "Años de escolaridad:",
                     Schooling, "<br>", "País:", Country
                     )) %>%
  add_markers() 

Nombres de los ejes y unidades

Quizas no la habías notado, pero hasta ahora, los nombres de los ejes son los nombres de las variables en los datos. Estos nombres, por lo general, no son apropiados a la hora de compartir estos gráficos en presentaciones o documentos. El gráfico a continuación muestra como cambiar los nombres de los ejes y agregar un tículo.

life2015 %>% 
  plot_ly(x = ~Schooling, y = ~Life.expectancy, color = ~Status, hoverinfo = "text", text = ~paste("Esperanza de vida:", Life.expectancy, "<br>", "Años de escolaridad:",
                     Schooling, "<br>", "País:", Country
                     )) %>%
  add_markers() %>%
  layout(xaxis = list(title = "Años de escolaridad"),
         yaxis = list(title = "Esperanza de vida"), 
         title = "¿Más educación se traduce en una vida mejor?") 

Múltiples gráficos en uno

Para incluir varios gráficos en un mismo espacio, plot_ly permite construir gráficos en capas. A continuación se muestra diferentes gráficos construídos en capas.

Líneas de tendencia

Cuando se cuenta con gráficos de dispersión, a veces queremos agregar líneas de tendencia para facilitar la interpretación de la relación entre las variables. El primer paso será crear el modelo. En este caso, crearemos dos modelos, uno lineal y uno loess, para compararlos.

La primera capa del gráfico consiste del gráfico de dispersión. Luego, usando la función add_lines, se agregaron dos capas adicionales, cada una correspondiente a una línea de tendencia previamente estimada.

modelo_lineal <- lm(Life.expectancy ~ Schooling, data = life2015)
modelo_loess <- loess(Life.expectancy ~ Schooling, data = life2015)

life2015 %>%
   select(Life.expectancy, Schooling) %>%
   na.omit() %>%
   plot_ly(x = ~Schooling, y = ~Life.expectancy) %>%
   add_markers(showlegend = FALSE) %>%
   add_lines(y = ~fitted(modelo_lineal), name = "Modelo lineal") %>%
  add_lines(y = ~fitted(modelo_loess), name = "Modelo loess")

Gráficos de densidad

Los gráficos de densidad son una alternativa a los histogramas. La diferencia es que, en lugar de mostrar la frecuencia, muestran la probabilidad.

En este ejemplo, se muestra la densidad de la esperanza de vida de los países desarrollados y los que están en vías de desarrollo. Para poder estimar la densidades, el primer paso es separar los datos en dos subgrupos, el de países desarrollado y el de países en vías de desarrollo. La opción na.rm = TRUE se encarga de omitir de los datos observaciones faltantes. Segundo, se calculan las densidad utilizando la función density. Finalmente, se superponen los gráficos. ¿En qué grupo de países es más probable vivir 80 años?

developed <- life2015 %>% filter(Status == "Developed") 
developing <- life2015 %>% filter(Status == "Developing") 

densidad.developed <- density(developed$Life.expectancy, na.rm = TRUE)
densidad.developing <- density(developing$Life.expectancy, na.rm = TRUE)

plot_ly() %>%
  add_lines(x = ~densidad.developed$x, y = ~densidad.developed$y, name = "Países desarrollado", fill = 'tozeroy') %>%
  add_lines(x = ~densidad.developing$x, y = ~densidad.developing$y, name = "Países en desarrollo", fill = 'tozeroy') %>%
  layout(xaxis = list(title = 'Esperanza de vida'),
         yaxis = list(title = 'Densidad'))

Matrices de gráficos

En algunas ocasiones queremos observar un mismo gráfico separado según los valores de otra variable. En el ejemplo a continuación, se muestra la relación entre Esperanza de vida y escolaridad separado el estatus del país. La opción shareY y shareX = TRUE nos permitira compartir la interactividad entre los sub-gráficos.

Para agregar un título al gráfico y etiquetar los ejes, únicamente agregamos el comando layout después de subplot. Note que tenemos dos ejes horizontales, así que es necesario nombrar ambos. De hecho, si lo desea, podrá nombrar todos los ejes que tenga en la matriz.

life2015 %>%
  group_by(Status) %>%
  do(
    plot = plot_ly(data = ., x = ~Schooling, y = ~Life.expectancy) %>%
      add_markers(name = ~Status)
  ) %>%
  subplot(nrows = 1, shareY = TRUE, shareX = TRUE) %>%
  layout(
    title = "Esperanza de vida según escolaridad",
    xaxis = list(title = "Escolaridad"), 
     xaxis2 = list(title = "Escolaridad"),
     yaxis = list(title = "Esperanza de vida") 
     )

Matriz de gráficos de diserpsión

La matriz de gráficos de dispersión es diferente a la matriz del inciso anterior debido a qué ésta nos permitira observar la relación entre tres o más variables continuas. Adicionalmente, con la opción de color, se ha agregado una variable categórica adicional.

matriz.dispersion <- life2015 %>%
  plot_ly(color = ~Status) %>%
  add_trace(
    type = 'splom',
    dimensions = list(
      list(label = 'Esperanza de vida', values = ~Life.expectancy),
      list(label = 'IMC', values = ~BMI),
      list(label = 'Scholaridad', values = ~Schooling)
    )
  )

matriz.dispersion

La información contenida en la diagonal y una de las mitades de la matriz no es realmente de utilidad. La diagonal es una correlación lineal perfecta, ya que es cada variable consigo misma, y una de las mitades simplemente es un reflejo de la otra. Con una simple línea de código podemos simplificar el gráfico para que muestre únicamente una de las mitades que nos interesa.

En el código anterior, la matriz de dispersión quedó guardada en el objeto matriz.dispersion, que podemos utilizar para agregarle una capa adicional que simplifique el gráfico. Tanto la diagnoal como las mitades se muestran por default, así que simplimente desactivamos esa opción en la función de style.

matriz.dispersion %>%
   style(diagonal = list(visible = FALSE), showlowerhalf = FALSE)

Diagramas de dispersión agrupados

En algunas ocasiones, cuando se cuenta con demasiadas observaciones, es posible que sobrecarguemos el gráfico y que limitemos su interpretación. Esto suele suceder principalmente con gráficos de dispersión. La base de datos original de la esperanza de vida cuenta con 2938 observación, que es aún pequeño para los casos de gráficos sobrecargados, pero que ayudará a ejemplificar los diagramas de dispersión agrupados. Al explorar el gráfico notará que se despliegan tres valores, dos correspondientes a los ejes horizantal (x) y vertial (y) y uno correspondiente a z. Este último indica la cantidad de observaciones que se encuentran en cada caja o grupo.

lifeexpectancy %>%
  plot_ly(x = ~BMI, y = ~Life.expectancy) %>%
  add_histogram2d(nbinsx = 50, nbinsy = 50)

Mapas

Cuando se cuenta con información de países o estados (según el país) es interesante poder visualizar la distribución espacial de las variables. A continuación se muestra un mapa con la distribución espacial de la esperana de vida. ¿Cómo se encuntra su país con respecto a los vecinos? Si lo desea, puede cambiar el texto que se muestra al navegar el gráfico utilizando la función the hoverinfo

life2015 %>%
  plot_geo(locationmode = 'country names') %>%
  add_trace(z = ~Life.expectancy, locations = ~Country) 

Si no desea colorear todo el mapa, puede agregar puntos a este, lo que le permitirá cambiar el tamaño del punto según la variable que desee. Para poder agregar punto al mapa, es necesario contar con la information de georeferencia (latitud y longitud). Debido a que esta base de datos no cuenta con dicha información, se omitirá este ejemplo. Sin embargo, no dude en consultarle al docente para que le enseñe como.