Unidad 2 Análisis exploratorio de datos

Esta unidad mostrará cómo utilizar la visualización y la transformación para explorar los datos de un diseño experimental de una manera sistemática, una tarea que los estadísticos llaman análisis exploratorio de datos, o AED (EDA en inglés) para abreviar. Los contenidos para este tema se han obtenido de Wickham and Grolemund (2016).

EDA es un ciclo iterativo en el que el investigador debe: este caso se irán mezclando los contenidos teóricos con los prácticos para ir mostrando el funcionamiento de las diferentes funciones y procedimientos para el análisis inicial de nuestro banco de datos.

  • Generar preguntas sobre tus datos.
  • Buscar respuestas visualizando, transformando y modelando sus datos.
  • Usar lo que aprende para refinar sus preguntas y / o generar nuevas preguntas.

EDA no es un proceso formal con un conjunto estricto de reglas. Más que nada, EDA es un estado mental. Durante las fases iniciales de EDA, debe sentirse libre de investigar cada idea que se le ocurra. Algunas de estas ideas funcionarán, y algunas serán callejones sin salida. A medida que continúe su exploración, se dirigirá a algunas áreas particularmente productivas que eventualmente escribirá y comunicará a otros.

El EDA es una parte importante de cualquier análisis de datos porque siempre debe investigar la calidad de sus datos. La limpieza de datos es solo una aplicación de EDA: el investigador debe hacer preguntas sobre si sus datos cumplen con sus expectativas o no. Para realizar la limpieza de datos, deberá implementar todas las herramientas de EDA: visualización, transformación y modelado.

2.1 Objetivos

El objetivo durante EDA es desarrollar una comprensión de los datos experimentales recogidos. La forma más fácil de hacerlo es utilizar preguntas como herramientas para guiar su investigación. Cuando se hace una pregunta, la pregunta centra la atención del investigador en una parte específica del conjunto de datos y le ayuda a decidir qué gráficos, modelos o transformaciones realizar.

EDA es fundamentalmente un proceso creativo. Como la mayoría de los procesos creativos, la clave para hacer preguntas de calidad es generar una gran cantidad de preguntas. Es difícil hacer preguntas reveladoras al comienzo del análisis porque el investigador no sabe qué información contiene su conjunto de datos. Por otro lado, cada nueva pregunta que haga le expondrá a un nuevo aspecto de sus datos y aumentará sus posibilidades de hacer un descubrimiento. Se puede profundizar rápidamente en las partes más interesantes de los datos experimentales recogidos y desarrollar una serie de preguntas que invitan a la reflexión, si se realiza un seguimiento de cada pregunta con una nueva pregunta basada en lo que se encuentre.

No hay una regla sobre qué preguntas se deben hacer para guiar la investigación, ya que debe ser el investigador en función de los objetivos del experimento planteado el que desarrolle dichas preguntas. Sin embargo, dos tipos de preguntas siempre serán útiles para hacer descubrimientos dentro de los datos. Estas preguntas son:

  • ¿Qué tipo de variabilidad ocurre dentro de las variables recogidas?
  • ¿Qué tipo de covariación (o variabilidad conjunta entre dos o más variables) ocurre entre las variables recogidas?

2.2 Variabilidad

La variabilidad es la tendencia de los valores de una variable a cambiar de medición a medición. Dicha variabilidad se parecía claramente en la vida real; si se mide cualquier variable continua dos veces, se obtendrán dos resultados diferentes. Esto es cierto incluso si se miden cantidades que son constantes, como la velocidad de la luz. Cada una de sus medidas incluirá una pequeña cantidad de error que varía de una medida a otra. Las variables categóricas también pueden variar si se miden diferentes sujetos (por ejemplo, los colores de los ojos de diferentes personas) o en diferentes momentos (por ejemplo, los niveles de energía de un electrón en diferentes momentos). Cada variable tiene su propio patrón de variación, que puede revelar información interesante. La mejor manera de entender ese patrón es visualizar la distribución de los valores de la variable mediante descriptores numéricos o gráficos.

Si la variación describe el comportamiento dentro de una variable, la covariación describe el comportamiento entre las variables. La covariación es la tendencia de los valores de dos o más variables a variar juntas de una manera relacionada. La mejor forma de detectar la covariación es visualizar la relación entre dos o más variables. Cómo hacer eso nuevamente debería depender del tipo de variables involucradas.

2.3 Procesado inicial

La descripción numérica y la visualización gráfica son las herramientas más importantes en los pasos iniciales para la generación de conocimiento sobre los datos experimentales, pero en ocasiones los datos no son recogidos en la forma más efectiva para realizar dichos análisis. A menudo se necesitara crear algunas variables o resúmenes nuevos, o tal vez solo se quiera cambiar el nombre de las variables o reordenar las observaciones para facilitar el trabajo de los datos. En este tema aprenderemos cómo hacer todo eso. Para ejemplificar los procedimientos utilizaremos el conjunto de datos flights contenido en la librería nycflights13, que contiene toda la información sobre los vuelos que salieron desde la ciudad de Nueva York en 2013.

Las variables que contiene este banco de datos (336776 observaciones = vuelos) son:

  • year: Fecha de salida (año).
  • month: Fecha de salida (mes).
  • year,month,day: Fecha de salida (día).
  • dep_time: Hora real de salida.
  • arr_time: Hora real de llegada (en horario de la ciudad de llegada).
  • sched_dep_time: Hora programada de salida. (Esta variable debe coincidir con la información de las variables hour y minute)
  • sched_arr_time: Hora programada de llegada (en horario de la ciudad de llegada).
  • dep_delay: Demora de salida (en minutos). Los tiempos negativos representan salidas tempranas.
  • arr_delay: Demora de llegada (en minutos). Los tiempos negativos representan llegadas tempranas.
  • hour: Hora de partida programada.
  • minute: Minuto de partida programada.
  • carrier: Aerolínea encargada del vuelo
  • tailnum: Identificador del avión
  • flight: Identificador del vuelo
  • origin: Origen del vuelo
  • dest: Destino del vuelo
  • air_time: Tiempo de vuelo (en minutos)
  • distance: Distancia entre los dos aeropuertos (en millas)
  • time_hour: Fecha y hora programadas del vuelo como una fecha POSIXct. Junto con el origen, se puede usar para unir datos de vuelos a datos meteorológicos.

Recuerda que debes instalar dicha librería antes de poder reproducir todo los procedimientos que mostramos en las secciones siguientes.

Instalamos la librería (junto con todas las necesarias para la asignatura) y cargamos los datos para poder visualizarlos:

library(nycflights13)

Código para cargar y visualizar los datos

# Carga de datos
data(flights)
# Visualización de los 10 primeros casos
kable(
  head(flights,10), align = 'c', booktabs = TRUE,
  caption = 'Datos flights de la librería nycflights13.')

Tambien podemos ver la estructura (tipo de variables) del banco de datos. Los tipos de variables que se admiten en R son: int para enteros, dbl para números reales, chr para vectores de caracteres o cadenas, dttm para fechas-tiempos (una fecha + una hora), lgl para vectores lógicos que solo contienen VERDADERO o FALSO, fctr para factores (que R usa para representar variables categóricas con valores posibles fijos), y date para fechas.

# Visualización de la estructura del banco de datos
str(flights)
## tibble [336,776 × 19] (S3: tbl_df/tbl/data.frame)
##  $ year          : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month         : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day           : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_time      : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
##  $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
##  $ dep_delay     : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_time      : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
##  $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
##  $ arr_delay     : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ carrier       : chr [1:336776] "UA" "UA" "AA" "B6" ...
##  $ flight        : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
##  $ tailnum       : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
##  $ origin        : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
##  $ dest          : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
##  $ air_time      : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ distance      : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ hour          : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
##  $ minute        : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...

2.3.1 Operaciones con sujetos

Los procedimientos para el trabajo con los sujetos de nuestra muestra se reducen al filtrado u ordenación, para quedarnos con un subconjunto de sujetos o para organizar su visualización en otra forma.

2.3.1.1 Filtrado

Usamos el filtrado para seleccionar un subconjunto de observaciones del data.frame que contiene nuestros datos. Esto se hace a menudo cuando queremos limitar un análisis a un subconjunto de observaciones. El uso básico del filtro se hace mediante la función filter():

filter(data_set, <expression1>, <expression2>, ...)

donde data_set es el nombre del objeto que contiene nuestros datos y <expression1>, <expression2>,...son uno o más argumentos adicionales, donde cada uno de estos es una expresión de R válida que implica una o más condiciones a aplicar sobre las variables del conjunto de datos. Cada expresión se interpreta como una condición lógica (verdadero o falso).

Para usar el filtrado de manera efectiva, se debe saber cómo seleccionar las observaciones que se desea utilizando los operadores de comparación. R proporciona el paquete estándar: > (mayor que), >= (mayor o igual que), < (menor que), <= (menor o igual que), != (no igual a), y == (igual a).

Veamos diferentes posibilidades de filtrado sobre el banco de datos flights. En primer lugar filtramos todos los vuelos cuya día de origen sea el 1 de enero de 2013. El resultado es un conjunto de datos con 842 observaciones donde aparece la información de dichos vuelos. Almacenamos el resultado eb nuevo objeto y calculamos el tamaño (nñumero de sujetos) con la función dim.

jan1 <- filter(flights, month == 1, day == 1)
dim(jan1)
## [1] 842  19

Podemos combinar diferentes condiciones de filtrado mediante los operadores lógicos & es “y” (condición 1 y condición 2), | es “o” (condición 1 o condición 2). Seleccionamos ahora todos los vuelos con mes de origen igual a Noviembre o Diciembre.

nov_dec <- filter(flights, month == 11 | month == 12)
dim(nov_dec) # Para saber cuantas observaciones contiene el banco de datos filtrado 
## [1] 55403    19

Los datos filtrados contienen la información completa de 55403 vuelos. Otra forma de conseguir el mismo resultado es con el operador %in%

nov_dec <- filter(flights, month %in% c(11, 12))
dim(nov_dec)
## [1] 55403    19

A veces se pueden simplificar condiciones de filtrado más complicadas sin más que recordar la ley de De Morgan: !(x & y) es lo mismo que!x | !y, y!(x | y)es lo mismo que!x & !y`. Por ejemplo, si se desean obtener todos vuelos que no se retrasaron (en llegada o partida) en más de dos horas, se pueden usar cualquiera de los dos filtros siguientes:

db_sel1 <- filter(flights, !(arr_delay > 120 | dep_delay > 120))
dim(db_sel1)
## [1] 316050     19
db_sel2 <- filter(flights, arr_delay <= 120, dep_delay <= 120)
dim(db_sel2)
## [1] 316050     19

2.3.1.2 Ordenación

Otro procesamiento muy habitual con los sujetos es reordenar las filas de un objeto que contiene nuestros datos. Esto se usa cuando queremos inspeccionar un conjunto de datos para buscar asociaciones entre las diferentes variables, lo que resulta difícil de hacer si no están ordenados. Para realizar la ordenación se utiliza la función arrange(). El uso básico de la función es:

arrange(data_set, varname1, varname2, ...)

donde data_set es el nombre del objeto que contiene nuestros datos y varname1, varname2,... son las variables que vamos a utilizar para la ordenación. Por ejemplo deseamos ordenar nuestro datos siguiendo el orden año, mes y día:

dbf_ord1 <- arrange(flights, year, month, day)
str(dbf_ord1)
## tibble [336,776 × 19] (S3: tbl_df/tbl/data.frame)
##  $ year          : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month         : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day           : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_time      : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
##  $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
##  $ dep_delay     : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_time      : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
##  $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
##  $ arr_delay     : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ carrier       : chr [1:336776] "UA" "UA" "AA" "B6" ...
##  $ flight        : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
##  $ tailnum       : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
##  $ origin        : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
##  $ dest          : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
##  $ air_time      : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ distance      : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ hour          : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
##  $ minute        : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...

Podemos introducir la función desc() para ordenar de forma descendente por la variable seleccionada. Ordenamos nuestros datos (de mayor a menor) por la demora en el tiempo de llegada:

dbf_ord2 <- arrange(flights, desc(arr_delay))
str(dbf_ord2)
## tibble [336,776 × 19] (S3: tbl_df/tbl/data.frame)
##  $ year          : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month         : int [1:336776] 1 6 1 9 7 4 3 7 12 5 ...
##  $ day           : int [1:336776] 9 15 10 20 22 10 17 22 5 3 ...
##  $ dep_time      : int [1:336776] 641 1432 1121 1139 845 1100 2321 2257 756 1133 ...
##  $ sched_dep_time: int [1:336776] 900 1935 1635 1845 1600 1900 810 759 1700 2055 ...
##  $ dep_delay     : num [1:336776] 1301 1137 1126 1014 1005 ...
##  $ arr_time      : int [1:336776] 1242 1607 1239 1457 1044 1342 135 121 1058 1250 ...
##  $ sched_arr_time: int [1:336776] 1530 2120 1810 2210 1815 2211 1020 1026 2020 2215 ...
##  $ arr_delay     : num [1:336776] 1272 1127 1109 1007 989 ...
##  $ carrier       : chr [1:336776] "HA" "MQ" "MQ" "AA" ...
##  $ flight        : int [1:336776] 51 3535 3695 177 3075 2391 2119 2047 172 3744 ...
##  $ tailnum       : chr [1:336776] "N384HA" "N504MQ" "N517MQ" "N338AA" ...
##  $ origin        : chr [1:336776] "JFK" "JFK" "EWR" "JFK" ...
##  $ dest          : chr [1:336776] "HNL" "CMH" "ORD" "SFO" ...
##  $ air_time      : num [1:336776] 640 74 111 354 96 139 167 109 149 112 ...
##  $ distance      : num [1:336776] 4983 483 719 2586 589 ...
##  $ hour          : num [1:336776] 9 19 16 18 16 19 8 7 17 20 ...
##  $ minute        : num [1:336776] 0 35 35 45 0 0 10 59 0 55 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-09 09:00:00" "2013-06-15 19:00:00" ...

En el resumen de los datos presentados se pueden apreciar las diferencia entre los datos ordenados de una u otra forma.

2.3.2 Trabajando con variables

Los procedimientos para el trabajo con las variables de nuestra muestra se reducen a la selección de un subconjunto de variables, la creación de nuevas variables, el renombrado de variables, y la recodificación en nuevas variables.

2.3.2.1 Selección

Usamos la función select() para seleccionar un subconjunto de variables de nuestro banco de datos. Esto función se usa cuando tenemos un conjunto de datos con muchas variables, pero solo necesitamos trabajar con un subconjunto de ellas. La función tiene la estructura:

select(data_set, varname1, varname2, ...)

El primer argumento, data_set, es el nombre del objeto que contiene nuestros datos. A continuación incluimos una serie de uno o más argumentos adicionales, donde cada uno es el nombre de una o más variables en el conjunto de datos. Estas son las variables que aparecerán en el nuevo banco de datos.

Para el conjunto de datos flights vamos a seleccionar las variables year, month, y day.

dbf_sel1 <- dplyr::select(flights, year, month, day)
# indicamos la libreria por la coincidencia de la función select()
# en otra libreria cargada
str(dbf_sel1) 
## tibble [336,776 × 3] (S3: tbl_df/tbl/data.frame)
##  $ year : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month: int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day  : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...

A veces es más conveniente establecer la selección especificando aquellas que no necesitamos, en lugar de especificar cuáles guardar. Usamos el operador - para indicar que variables deben ser eliminadas.

dbf_sel2 <- dplyr::select(flights, -(year:day)) 
# No seleccionamos las varaibles que se encuentran entre las variables year y day
str(dbf_sel2)
## tibble [336,776 × 16] (S3: tbl_df/tbl/data.frame)
##  $ dep_time      : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
##  $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
##  $ dep_delay     : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_time      : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
##  $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
##  $ arr_delay     : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ carrier       : chr [1:336776] "UA" "UA" "AA" "B6" ...
##  $ flight        : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
##  $ tailnum       : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
##  $ origin        : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
##  $ dest          : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
##  $ air_time      : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ distance      : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ hour          : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
##  $ minute        : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...

Cuando las variables que deseamos eliminar no se muestran de forma consecutiva en nuestro banco de datos podemos utilizar una expresión equivalente

dbf_sel3 <- dplyr::select(flights, -c(year,month,day)) 
str(dbf_sel3)
## tibble [336,776 × 16] (S3: tbl_df/tbl/data.frame)
##  $ dep_time      : int [1:336776] 517 533 542 544 554 554 555 557 557 558 ...
##  $ sched_dep_time: int [1:336776] 515 529 540 545 600 558 600 600 600 600 ...
##  $ dep_delay     : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_time      : int [1:336776] 830 850 923 1004 812 740 913 709 838 753 ...
##  $ sched_arr_time: int [1:336776] 819 830 850 1022 837 728 854 723 846 745 ...
##  $ arr_delay     : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ carrier       : chr [1:336776] "UA" "UA" "AA" "B6" ...
##  $ flight        : int [1:336776] 1545 1714 1141 725 461 1696 507 5708 79 301 ...
##  $ tailnum       : chr [1:336776] "N14228" "N24211" "N619AA" "N804JB" ...
##  $ origin        : chr [1:336776] "EWR" "LGA" "JFK" "JFK" ...
##  $ dest          : chr [1:336776] "IAH" "IAH" "MIA" "BQN" ...
##  $ air_time      : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ distance      : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ hour          : num [1:336776] 5 5 5 5 6 5 6 6 6 6 ...
##  $ minute        : num [1:336776] 15 29 40 45 0 58 0 0 0 0 ...
##  $ time_hour     : POSIXct[1:336776], format: "2013-01-01 05:00:00" "2013-01-01 05:00:00" ...

2.3.2.2 Creación

En la creación de variables a partir de las originales en nuestros datos tenemos dos opciones: i) crear una nueva variable sin eliminar las variables originales, ii) crear una nueva variable eliminando las variables originales.

Usamos la función mutate() para crear nuevas variables en nuestro banco de datos sin eliminar las variables que forman parte de la nueva variable. La función tiene la estructura:

mutate(data_set, <expression1>, <expression2>, ...)

El primer argumento, data_set, es el nombre del objeto que contiene nuestros datos. A continuación incluimos una serie de uno o más argumentos adicionales, donde cada uno es la expresión para la nueva o nuevas variables.

Veamos un ejemplo de uso de la función

dbf_sel4 <- dplyr::select(flights, c(year,month,day,dep_delay,arr_delay,distance,air_time)) 
# Seleccionamos un subconjunto de las variables originales
str(dbf_sel4)
## tibble [336,776 × 7] (S3: tbl_df/tbl/data.frame)
##  $ year     : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month    : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day      : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_delay: num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_delay: num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ distance : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ air_time : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
# Creamos una varaible que indica la reducción de demora entre salida y llegada
# Calculamos la velocidad del viaje
dbf_new <- mutate(dbf_sel4,
  gain = arr_delay - dep_delay,
  speed = distance / air_time * 60
) 
str(dbf_new)
## tibble [336,776 × 9] (S3: tbl_df/tbl/data.frame)
##  $ year     : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month    : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day      : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_delay: num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_delay: num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ distance : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ air_time : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ gain     : num [1:336776] 9 16 31 -17 -19 16 24 -11 -5 10 ...
##  $ speed    : num [1:336776] 370 374 408 517 394 ...

Podemos ver que se han añadido las dos variables en el nuevo banco de datos que se ha creado. Una ventaja de esta función es que resulta posible crear nuevas variables a partir de las nuevas creadas

dbf_new2 <- mutate(dbf_sel4,
  gain = arr_delay - dep_delay,
  hours = air_time / 60,
  gain_per_hour = gain / hours
) 
str(dbf_new2)
## tibble [336,776 × 10] (S3: tbl_df/tbl/data.frame)
##  $ year         : int [1:336776] 2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
##  $ month        : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ day          : int [1:336776] 1 1 1 1 1 1 1 1 1 1 ...
##  $ dep_delay    : num [1:336776] 2 4 2 -1 -6 -4 -5 -3 -3 -2 ...
##  $ arr_delay    : num [1:336776] 11 20 33 -18 -25 12 19 -14 -8 8 ...
##  $ distance     : num [1:336776] 1400 1416 1089 1576 762 ...
##  $ air_time     : num [1:336776] 227 227 160 183 116 150 158 53 140 138 ...
##  $ gain         : num [1:336776] 9 16 31 -17 -19 16 24 -11 -5 10 ...
##  $ hours        : num [1:336776] 3.78 3.78 2.67 3.05 1.93 ...
##  $ gain_per_hour: num [1:336776] 2.38 4.23 11.62 -5.57 -9.83 ...

Usamos la función transmute() para crear un banco de datos donde solo aparecen las nuevas variables creadas. La estructura de la función es idéntica a la de la función mutate().

dbf_new3 <- transmute(dbf_sel4,
  gain = arr_delay - dep_delay,
  hours = air_time / 60,
  gain_per_hour = gain / hours
) 
str(dbf_new3)
## tibble [336,776 × 3] (S3: tbl_df/tbl/data.frame)
##  $ gain         : num [1:336776] 9 16 31 -17 -19 16 24 -11 -5 10 ...
##  $ hours        : num [1:336776] 3.78 3.78 2.67 3.05 1.93 ...
##  $ gain_per_hour: num [1:336776] 2.38 4.23 11.62 -5.57 -9.83 ...

El listado de funciones que podemos usar con las funciones mutate() y transmute() son:

  • Operadores aritméticos: +, -, *, /, ^
  • Funciones logaritmo: log(), log2(), log10()
  • Funciones de agregación: cumsum() (suma acumulada), cumprod() (producto acumulado), cummin() (mínimo acumulado), cummax() (máximo acumulado), cummean() (media acumulada).
  • Comparaciones lógicas: <, <=, >, >=, !=

2.3.2.3 Creación de factores

La creación de variables tipo factor es un aspecto muy importante en el análisis de datos. Existen tres formas principales de conseguir variables de tipo factor:

  1. A partir de variables tipo carácter
  2. A partir de variables de tipo entero que pueden identificar niveles de una variable
  3. A partir de una variable de tipo numérico.

Por el momento solo mostraremos las opciones 1 y 2. La función utilizada para estas operaciones es fct_recode() cuya estructura viene dada por:

fct_recode(varfactor, levelnew1=levelold1, levelnew2=levelold2, ...)

donde varfactor es la variable factor original, levelnew son los niveles del factor recodificados y levelold son los niveles del factor en la variable original.

Vamos a ver un ejemplo de su uso sobre el banco de datos NCBIRTH800 que presentamos en la unidad anterior. Cargamos los datos desde el repositorio y vemos su estructura:

NCBIRTH800=read_csv("https://goo.gl/mB9Jcn", col_types = "dcddcccdccddcc")

En esta base de datos hay varias variables que se han recogido como carácter (aunque se les ha asignado un código numérico). A continuación se presentan dichas variables así como la asignación de valor a cada uno de los códigos numéricos:

sex: "male" = 1,"female" = 2
marital: "married" = 1,"not married" = 2
racemom: "other non white" = 0, "White" = 1,"Black" = 2,
         "America indian" = 3,"Chinese" = 4,"Hawaiian" = 5,
         "Filipino" = 6,"Other asian" = 7, "Other" = 8
hispmom: "Cuban" = C, "Mexican" = M, "Non-Hispanic" = N ,
         "Other" = O,"Puerto Rican" = P, "Central/South american" = S,
         "U" = Not classificable
smoke: "Yes"=1, "No" = 0
drink: "Yes" = 1 ,"No" = 0
low: "Yes" = 1, "No" = 0
premie: "Yes"= 1, "No" = 0

Realizamos la asignación de los valores

NCBIRTHnew <- mutate(NCBIRTH800,      
              sex = fct_recode(sex,"male" = "1","female" = "2"),
              marital = fct_recode(marital,"married" = "1","not married" = "2"),
              racemom = fct_recode(racemom,"other non white" = "0","White" = "1",
                                   "Black" = "2","America  indian" = "3",
                                   "Chinese" = "4","Hawaiian" = "5","Filipino" = "6",
                                   "Other asian" = "7","Other" = "8"),
              hispmom = fct_recode(hispmom,"Cuban" = "C","Mexican" = "M",
                                   "Non-Hispanic" = "N","Other" = "O",
                                   "Puerto Rican" = "P","Central/South american" = "S",
                                   "U" = "Not classificable"),
              smoke = fct_recode(smoke,"Yes" = "1","No" = "0"),
              drink = fct_recode(drink,"Yes" = "1","No" = "0"),
              low = fct_recode(low,"Yes" = "1","No" = "0"),
              premie = fct_recode(premie,"Yes" = "1","No" = "0"))
str(NCBIRTHnew)
## spec_tbl_df [800 × 14] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ plural : num [1:800] 1 1 1 1 1 1 1 1 1 1 ...
##  $ sex    : Factor w/ 2 levels "male","female": 1 2 1 1 1 1 2 2 2 2 ...
##  $ mage   : num [1:800] 32 32 27 27 25 28 25 15 37 21 ...
##  $ weeks  : num [1:800] 40 37 39 39 39 43 39 42 41 39 ...
##  $ marital: Factor w/ 2 levels "married","not married": 1 1 1 1 1 1 1 2 1 1 ...
##  $ racemom: Factor w/ 6 levels "White","Black",..: 1 1 1 1 1 1 1 1 6 1 ...
##  $ hispmom: Factor w/ 6 levels "Cuban","Mexican",..: 3 3 3 3 3 3 3 3 3 3 ...
##  $ gained : num [1:800] 38 34 12 15 32 32 75 25 31 28 ...
##  $ smoke  : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
##  $ drink  : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
##  $ tounces: num [1:800] 111 116 138 136 121 117 143 113 139 120 ...
##  $ tgrams : num [1:800] 3147 3289 3912 3856 3430 ...
##  $ low    : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
##  $ premie : Factor w/ 2 levels "No","Yes": 1 1 1 1 1 1 1 1 1 1 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   plural = col_double(),
##   ..   sex = col_character(),
##   ..   mage = col_double(),
##   ..   weeks = col_double(),
##   ..   marital = col_character(),
##   ..   racemom = col_character(),
##   ..   hispmom = col_character(),
##   ..   gained = col_double(),
##   ..   smoke = col_character(),
##   ..   drink = col_character(),
##   ..   tounces = col_double(),
##   ..   tgrams = col_double(),
##   ..   low = col_character(),
##   ..   premie = col_character()
##   .. )
##  - attr(*, "problems")=<externalptr>

En el resultado se aprecia la modificación de los diferentes factores.

2.3.3 Reuniendo los datos

Un problema bastante común que parece en la recogida de datos experimentales es que los nombres de las columnas de la base de datos no es una variable en si, sino los valores de una variable. Si tomamos como ejemplo el banco de datos PCKDATA.

PCKDATA = read_csv("https://goo.gl/W8Bfgv", col_types = "idd")
PCKDATA
Tabla 2.1:
SUBJAB
1193250
290173
3120135
415449
514983
6146123
7180126
8128177
9180164
1066121
11129200
1217075
13121182
14135169
15133234
1616567
1712553
18129119
19118241
20109138
2189113
22115112
23119104
24200115
25158224
26130138
27197223
28165172
298068
30161164
31189232
32175106
33120266
34117190
3544153
3610259
37174119
389993
39126162
4047130
4113289
42177197
43144189
44177207
45161109
4684147
47180193
48198110
4915887
50116135
51176115
52111159
53109115
54181114
55108202
5657134
5715564
5823979
5910396
60158181
6124091
62136167
63182200
64176236
65113126
66158185
67118141
68184180
6911660
70124137
71173195
72241172
73141116
74150229
75172142
76179131
77146155
7889152
79149246
80140169
8110099
82124163
8390124
8499189
8520879
8622576
87203154
88130182
8999100
90209140
91185115
92190190
93148193
9488146
95141143
9662163
97256157
98198161
99150192
100145105
101201162
102164201
103207203
104178179
105145132
106139158
10760147
108125147
109140161
11014858
1115991
112128151
113135183
114173153
11582130
116175126
117140176
11814056
119187160
120165183
121126157
122142132
123167183
124120201
125154122
126125159
127131115
128119150
12912993
130111104
131150228
132153184
13355108
134118159
135131134
136171134
13713786
138175102
13960164
140202133
141175164
142140175
14313393
144104137
145129130
146118158
147265160
148171211
14911071
150114215
151153116
152110119
153190154
154187139
155131169
15611514
15713074
158182130
159152105
160192145
16164179
162148143
163182220
164135213
165202124
16684167
167121121
16890162
169187133
17013772
17113888
172187193
17313796
174204157
175148102
176185157
177120145
178125113
179196185
18020779
181145154
18283184
18317490
184118146
185136175
186123176
18786172
188102109
189102136
190150102
191222148
19217496
193179210
19418821
19575116
19696152
197152187
198150149
199130168
200161134
20177213
20210355
203127152
20414674
20513024
206200106
20790192
20883111
209122112
210122178
211233176
212154150
213125194
214164193
215187143
216192157
21799154
2189769
21914069
220137181
221178223
222207121
223123187
224151155
225206159
226102150
22716655
228171147
229154148
230197112
231111103
232148110
23378140
234192124
235239101
236131120
23767183
23842178
23912180
240180126
24170164
24281193
243167182
244119146
245109119
246175184
247152162
24894120
24964186
250127193
25177210
252190184
253169160
25415853
255111122
256123185
25739147
258152177
259211159
26014970
26113789
26279309
263127132
264116166
265150190
266130169
26759122
268205136
26914978
270149243
271177162
271147174
273153179
274185119
275140171
27611990
2778878
278137131
279173175
28059113
281199122
282160129
28380182
284122107
285131147
28673115
287229136
288242124
28997138
29012785
29113270
29284151
293120155
294161203
29513791
296194143
297178161
298205178
29911477
300120195
30193181
30212591
30311499
304190128
305136129
306114138
307109190
308164178
30970173
3105667
311156116
31272159
31374140
31474162
31512690
31653154
317158178
318182157
319101192
320127153
321114171
322201120
323137178
32479240
325181122
3268652
327109126
328120187
329101112
330184192
331169144
33212582
33316991
334123113
335170151
33683155
337121150
338121216
33919983
34094138
341195199
34292126
34321271
34416480
345216152
346178181
347219115
348142179
349143175
350104134
351124139
352122165
35315813
354129183
35583137
356144101
357183202
358132139
359134163
36097114
361179106
362141150
36398188
36419162
365181130
366165275
367119184
368161138
369103154
37015937
37113019
372115216
373120128
37418917
375125224
376125169
377190128
378127140
379105157
38098118
381154152
382113140
38368143
384191138
38519099
386191115
387153157
388141178
389143142
39071218
391135117
392153212
393145193
394117101
395163100
396185163
397213221
39896100
3993995
400226132
40188149
402151167
403140101
404124116
405165124
40650149
407159222
408131101
409154218
410140132
411126202
4127976
413120151
41416356
41511070
416147257
417153172
418191121
419217155
420102154
421242117
422179219
42311566
42476125
425156230
426205224
427114151
42896108
42999155
430170156
431141196
432162131
43317990
434205140
435114149
43616544
437121193
438130139
439250188
44090190
44195211
442163171
443157164
44492135
445173123
44698174
447155123
44819292
449152142
450158259
451189142
452120147
453131157
45415987
45598164
456124217
45783156
458148201
459131140
460186134
461151146
46288168
463149130
46489189
465104168
466148143
46710383
468106139
4696986
47049121
471173160
472163114
473207202
474134156
475125204
47673170
477160160
478205183
47921357
480254152
48167133
482172237
48313882
484158170
485221149
48676102
487207164
488110165
489196157
490102193
491202141
492139134
49387176
494237113
495169140
49622245
497181157
49865102
49920768
50056108
50122140
502173126
503183129
504224155
50597229
506206198
50781178
508124142
509136201
510143135
51113699
51217043
513118143
51472121
515146110
516130197
517178200
5189187
519133171
520165161
521176140
52211042
523235192
52454109
52516097
526161119
52717375
528107164
52913290
530147196
531124193
532129125
533273110
53490178
535209146
536229217
537105141
538173181
539154225
54014965
54192144
542129114
543141191
544198192
545114150
546124159
547222139
548107169
549147156
55022021
55182156
55217891
553196121
554248122
555186111
556101124
557116146
558157109
559167173
56011395
561135206
562162158
563140134
564111152
565240167
56661141
56756158
568165192
569160131
570191124
571146192
57264146
573148110
574125170
575193201
57625191
577154131
57868214
579217153
580264186
581115148
582153125
583152155
584177132
585117171
5868769
58719993
588143152
589219205
590136128
59198165
592161210
593201155
59416571
595120177
59623118
597180182
598123157
599220196
600148119
601113156
602162209
603115154
60473128
60511692
606173127
6074893
608161191
609183212
61012897
61195141
612212191
613119128
61414075
61599166
616194132
61717868
618142139
61912373
62013173
621205149
622136136
62317352
624188134
62517272
62613067
62710896
628140100
629193184
63081224
63121258
632169193
633175150
634195135
635130151
636140138
637130207
63863158
63967223
640202124
641127129
642200173
64391179
644129142
64511693
646163101
647127166
648148177
64912388
650232153
65117274
652155111
65350176
654134125
655102122
656183170
6579496
658103200
659117170
660122204
66148146
662145136
663130123
664114101
665159106
666127129
667168169
668178109
66913587
67015170
671181160
672109136
673184125
67490247
675107131
67618682
677207104
678142167
6796299
680154176
681196114
682141201
683170148
684207154
685109155
686201128
687170192
688200199
6897699
690148159
69111191
6927898
69332158
694217106
695166219
69679177
697184143
698199192
699178109
70020261
701141229
702121158
703169134
704158130
705211106
706241117
707120210
708243252
70999119
710192122
71111545
71283130
71316399
714197187
71513484
716260160
717186103
71813953
71964118
720257164
72199128
722155141
723150192
724179183
725153222
726181129
727142178
728115114
729166157
73091145
731216148
732121126
733204194
734193176
735113174
73691198
737175121
738198109
739185145
740166184
74193201
742152122
743170190
744124118
745112124
746153161
747179151
74894150
74921796
750139136
751176173
75274229
753146192
754114235
755213164
756143173
757171145
758124132
75983178
76091107
761107136
76298177
76313074
764150113
76518972
76617896
767177151
768164151
769157117
770116112
77116589
772167177
773126109
774191106
775253188
77616790
777181162
778128161
779192120
780164160
781195160
782200128
783132140
784135141
78516089
786160191
78750144
78815354
78985147
790133218
791172172
792139132
793103125
794145125
795143144
796170145
79720879
798119140
799100180
800138203
801159148
802168164
803250127
804209156
805114116
806221170
807217145
808145228
809240137
810123136
811144162
812142132
813172119
81410397
815143168
81618672
81779116
818135151
819124200
82088155
821215139
82276151
82316694
824221202
82592108
826137334
827201134
828169171
82912691
830218102
83114483
832269154
833126221
83496188
83511930
836121102
837188207
838185112
839165216
84018098
84165166
84266180
843109122
844131186
845142110
846138190
847178191
848165234
849121184
85093223
851134158
852139162
853138121
85474143
85534150
85677134
8579648
858200173
859138124
860175133
861134103
862164137
86310685
864153179
865203176
866160100
86768204
868207173
869139141
870122123
871128200
872244111
87370143
87482117
87516370
876265169
877203206
878213159
87975177
880152135
881110103
882155105
883181115
88414252
88565161
886150111
887236156
88819656
889146105
89016090
891148137
892205164
893162156
894204154
895128195
896201181
89776163
898206181
899157101
900123164
901116129
902113191
90379169
904156169
905113196
906132140
90714190
908159179
90956171
91014192
911260162
912113134
913110117
914120130
915143145
91624896
917162115
918159128
919155208
92020596
921143173
92221699
923164120
924168183
92578193
926188150
927193174
92888119
929169154
930148137
931111112
932164113
93311964
934146130
935112188
936141199
93770186
93893120
939137112
940105112
941129134
94222354
943135173
944172199
94535129
946194181
94718591
948148147
949107131
950161131
951127168
952190135
953133132
954149114
955118212
956203119
957166109
958161137
95919369
960109173
961215116
96272141
963168130
964130173
96599183
966116177
967196161
96861164
9695995
970103115
971146189
972118220
973128145
97487158
97585177
976180200
977120203
978149108
979233101
980188111
981135185
98298199
983160154
984151106
985121125
986149137
987173150
988100107
98999122
990156146
99177197
992210172
993160179
994135105
99525473
996186156
997100129
998191110
99976165
1000127208
100195150
100213192
1003135135
1004184126
1005157155

Como se puede ver aparecen dos columnas indicando el tratamiento del sujeto, es decir, cada fila no identifica a un único sujeto. Por ese motivo en cada una de ellas aparece el valor del nivel de creatinina. Para poder trabajar de forma óptima cada fila debe contener la información única de cada sujeto. En este caso cada fila contiene la información de dos sujetos: el identificado como 1 en el tratamiento A y el identificado como 1 en el tratamiento B.

La función gather()nos permite reorganizar los datos de un banco de datos de forma muy sencilla. La estructura básica de la función es:

gather(data_set,var, key = "key", value = "value", ...)

donde data_set es el banco de datos, var es el conjunto de variables que reorganizamos, key es el nombre de la variable donde reorganizamos las variables anteriores, y value es el nombre de la variable donde almacenamos los valores de respuesta. Para el conjunto de datos anterior tenemos:

gather(PCKDATA,`A`,`B`, key = "Grupo", value = creatine)
Tabla 2.2:
SUBJGrupocreatine
1A193
2A90
3A120
4A154
5A149
6A146
7A180
8A128
9A180
10A66
11A129
12A170
13A121
14A135
15A133
16A165
17A125
18A129
19A118
20A109
21A89
22A115
23A119
24A200
25A158
26A130
27A197
28A165
29A80
30A161
31A189
32A175
33A120
34A117
35A44
36A102
37A174
38A99
39A126
40A47
41A132
42A177
43A144
44A177
45A161
46A84
47A180
48A198
49A158
50A116
51A176
52A111
53A109
54A181
55A108
56A57
57A155
58A239
59A103
60A158
61A240
62A136
63A182
64A176
65A113
66A158
67A118
68A184
69A116
70A124
71A173
72A241
73A141
74A150
75A172
76A179
77A146
78A89
79A149
80A140
81A100
82A124
83A90
84A99
85A208
86A225
87A203
88A130
89A99
90A209
91A185
92A190
93A148
94A88
95A141
96A62
97A256
98A198
99A150
100A145
101A201
102A164
103A207
104A178
105A145
106A139
107A60
108A125
109A140
110A148
111A59
112A128
113A135
114A173
115A82
116A175
117A140
118A140
119A187
120A165
121A126
122A142
123A167
124A120
125A154
126A125
127A131
128A119
129A129
130A111
131A150
132A153
133A55
134A118
135A131
136A171
137A137
138A175
139A60
140A202
141A175
142A140
143A133
144A104
145A129
146A118
147A265
148A171
149A110
150A114
151A153
152A110
153A190
154A187
155A131
156A115
157A130
158A182
159A152
160A192
161A64
162A148
163A182
164A135
165A202
166A84
167A121
168A90
169A187
170A137
171A138
172A187
173A137
174A204
175A148
176A185
177A120
178A125
179A196
180A207
181A145
182A83
183A174
184A118
185A136
186A123
187A86
188A102
189A102
190A150
191A222
192A174
193A179
194A188
195A75
196A96
197A152
198A150
199A130
200A161
201A77
202A103
203A127
204A146
205A130
206A200
207A90
208A83
209A122
210A122
211A233
212A154
213A125
214A164
215A187
216A192
217A99
218A97
219A140
220A137
221A178
222A207
223A123
224A151
225A206
226A102
227A166
228A171
229A154
230A197
231A111
232A148
233A78
234A192
235A239
236A131
237A67
238A42
239A121
240A180
241A70
242A81
243A167
244A119
245A109
246A175
247A152
248A94
249A64
250A127
251A77
252A190
253A169
254A158
255A111
256A123
257A39
258A152
259A211
260A149
261A137
262A79
263A127
264A116
265A150
266A130
267A59
268A205
269A149
270A149
271A177
271A147
273A153
274A185
275A140
276A119
277A88
278A137
279A173
280A59
281A199
282A160
283A80
284A122
285A131
286A73
287A229
288A242
289A97
290A127
291A132
292A84
293A120
294A161
295A137
296A194
297A178
298A205
299A114
300A120
301A93
302A125
303A114
304A190
305A136
306A114
307A109
308A164
309A70
310A56
311A156
312A72
313A74
314A74
315A126
316A53
317A158
318A182
319A101
320A127
321A114
322A201
323A137
324A79
325A181
326A86
327A109
328A120
329A101
330A184
331A169
332A125
333A169
334A123
335A170
336A83
337A121
338A121
339A199
340A94
341A195
342A92
343A212
344A164
345A216
346A178
347A219
348A142
349A143
350A104
351A124
352A122
353A158
354A129
355A83
356A144
357A183
358A132
359A134
360A97
361A179
362A141
363A98
364A191
365A181
366A165
367A119
368A161
369A103
370A159
371A130
372A115
373A120
374A189
375A125
376A125
377A190
378A127
379A105
380A98
381A154
382A113
383A68
384A191
385A190
386A191
387A153
388A141
389A143
390A71
391A135
392A153
393A145
394A117
395A163
396A185
397A213
398A96
399A39
400A226
401A88
402A151
403A140
404A124
405A165
406A50
407A159
408A131
409A154
410A140
411A126
412A79
413A120
414A163
415A110
416A147
417A153
418A191
419A217
420A102
421A242
422A179
423A115
424A76
425A156
426A205
427A114
428A96
429A99
430A170
431A141
432A162
433A179
434A205
435A114
436A165
437A121
438A130
439A250
440A90
441A95
442A163
443A157
444A92
445A173
446A98
447A155
448A192
449A152
450A158
451A189
452A120
453A131
454A159
455A98
456A124
457A83
458A148
459A131
460A186
461A151
462A88
463A149
464A89
465A104
466A148
467A103
468A106
469A69
470A49
471A173
472A163
473A207
474A134
475A125
476A73
477A160
478A205
479A213
480A254
481A67
482A172
483A138
484A158
485A221
486A76
487A207
488A110
489A196
490A102
491A202
492A139
493A87
494A237
495A169
496A222
497A181
498A65
499A207
500A56
501A221
502A173
503A183
504A224
505A97
506A206
507A81
508A124
509A136
510A143
511A136
512A170
513A118
514A72
515A146
516A130
517A178
518A91
519A133
520A165
521A176
522A110
523A235
524A54
525A160
526A161
527A173
528A107
529A132
530A147
531A124
532A129
533A273
534A90
535A209
536A229
537A105
538A173
539A154
540A149
541A92
542A129
543A141
544A198
545A114
546A124
547A222
548A107
549A147
550A220
551A82
552A178
553A196
554A248
555A186
556A101
557A116
558A157
559A167
560A113
561A135
562A162
563A140
564A111
565A240
566A61
567A56
568A165
569A160
570A191
571A146
572A64
573A148
574A125
575A193
576A251
577A154
578A68
579A217
580A264
581A115
582A153
583A152
584A177
585A117
586A87
587A199
588A143
589A219
590A136
591A98
592A161
593A201
594A165
595A120
596A23
597A180
598A123
599A220
600A148
601A113
602A162
603A115
604A73
605A116
606A173
607A48
608A161
609A183
610A128
611A95
612A212
613A119
614A140
615A99
616A194
617A178
618A142
619A123
620A131
621A205
622A136
623A173
624A188
625A172
626A130
627A108
628A140
629A193
630A81
631A212
632A169
633A175
634A195
635A130
636A140
637A130
638A63
639A67
640A202
641A127
642A200
643A91
644A129
645A116
646A163
647A127
648A148
649A123
650A232
651A172
652A155
653A50
654A134
655A102
656A183
657A94
658A103
659A117
660A122
661A48
662A145
663A130
664A114
665A159
666A127
667A168
668A178
669A135
670A151
671A181
672A109
673A184
674A90
675A107
676A186
677A207
678A142
679A62
680A154
681A196
682A141
683A170
684A207
685A109
686A201
687A170
688A200
689A76
690A148
691A111
692A78
693A32
694A217
695A166
696A79
697A184
698A199
699A178
700A202
701A141
702A121
703A169
704A158
705A211
706A241
707A120
708A243
709A99
710A192
711A115
712A83
713A163
714A197
715A134
716A260
717A186
718A139
719A64
720A257
721A99
722A155
723A150
724A179
725A153
726A181
727A142
728A115
729A166
730A91
731A216
732A121
733A204
734A193
735A113
736A91
737A175
738A198
739A185
740A166
741A93
742A152
743A170
744A124
745A112
746A153
747A179
748A94
749A217
750A139
751A176
752A74
753A146
754A114
755A213
756A143
757A171
758A124
759A83
760A91
761A107
762A98
763A130
764A150
765A189
766A178
767A177
768A164
769A157
770A116
771A165
772A167
773A126
774A191
775A253
776A167
777A181
778A128
779A192
780A164
781A195
782A200
783A132
784A135
785A160
786A160
787A50
788A153
789A85
790A133
791A172
792A139
793A103
794A145
795A143
796A170
797A208
798A119
799A100
800A138
801A159
802A168
803A250
804A209
805A114
806A221
807A217
808A145
809A240
810A123
811A144
812A142
813A172
814A103
815A143
816A186
817A79
818A135
819A124
820A88
821A215
822A76
823A166
824A221
825A92
826A137
827A201
828A169
829A126
830A218
831A144
832A269
833A126
834A96
835A119
836A121
837A188
838A185
839A165
840A180
841A65
842A66
843A109
844A131
845A142
846A138
847A178
848A165
849A121
850A93
851A134
852A139
853A138
854A74
855A34
856A77
857A96
858A200
859A138
860A175
861A134
862A164
863A106
864A153
865A203
866A160
867A68
868A207
869A139
870A122
871A128
872A244
873A70
874A82
875A163
876A265
877A203
878A213
879A75
880A152
881A110
882A155
883A181
884A142
885A65
886A150
887A236
888A196
889A146
890A160
891A148
892A205
893A162
894A204
895A128
896A201
897A76
898A206
899A157
900A123
901A116
902A113
903A79
904A156
905A113
906A132
907A141
908A159
909A56
910A141
911A260
912A113
913A110
914A120
915A143
916A248
917A162
918A159
919A155
920A205
921A143
922A216
923A164
924A168
925A78
926A188
927A193
928A88
929A169
930A148
931A111
932A164
933A119
934A146
935A112
936A141
937A70
938A93
939A137
940A105
941A129
942A223
943A135
944A172
945A35
946A194
947A185
948A148
949A107
950A161
951A127
952A190
953A133
954A149
955A118
956A203
957A166
958A161
959A193
960A109
961A215
962A72
963A168
964A130
965A99
966A116
967A196
968A61
969A59
970A103
971A146
972A118
973A128
974A87
975A85
976A180
977A120
978A149
979A233
980A188
981A135
982A98
983A160
984A151
985A121
986A149
987A173
988A100
989A99
990A156
991A77
992A210
993A160
994A135
995A254
996A186
997A100
998A191
999A76
1000A127
1001A95
1002A131
1003A135
1004A184
1005A157
1B250
2B173
3B135
4B49
5B83
6B123
7B126
8B177
9B164
10B121
11B200
12B75
13B182
14B169
15B234
16B67
17B53
18B119
19B241
20B138
21B113
22B112
23B104
24B115
25B224
26B138
27B223
28B172
29B68
30B164
31B232
32B106
33B266
34B190
35B153
36B59
37B119
38B93
39B162
40B130
41B89
42B197
43B189
44B207
45B109
46B147
47B193
48B110
49B87
50B135
51B115
52B159
53B115
54B114
55B202
56B134
57B64
58B79
59B96
60B181
61B91
62B167
63B200
64B236
65B126
66B185
67B141
68B180
69B60
70B137
71B195
72B172
73B116
74B229
75B142
76B131
77B155
78B152
79B246
80B169
81B99
82B163
83B124
84B189
85B79
86B76
87B154
88B182
89B100
90B140
91B115
92B190
93B193
94B146
95B143
96B163
97B157
98B161
99B192
100B105
101B162
102B201
103B203
104B179
105B132
106B158
107B147
108B147
109B161
110B58
111B91
112B151
113B183
114B153
115B130
116B126
117B176
118B56
119B160
120B183
121B157
122B132
123B183
124B201
125B122
126B159
127B115
128B150
129B93
130B104
131B228
132B184
133B108
134B159
135B134
136B134
137B86
138B102
139B164
140B133
141B164
142B175
143B93
144B137
145B130
146B158
147B160
148B211
149B71
150B215
151B116
152B119
153B154
154B139
155B169
156B14
157B74
158B130
159B105
160B145
161B179
162B143
163B220
164B213
165B124
166B167
167B121
168B162
169B133
170B72
171B88
172B193
173B96
174B157
175B102
176B157
177B145
178B113
179B185
180B79
181B154
182B184
183B90
184B146
185B175
186B176
187B172
188B109
189B136
190B102
191B148
192B96
193B210
194B21
195B116
196B152
197B187
198B149
199B168
200B134
201B213
202B55
203B152
204B74
205B24
206B106
207B192
208B111
209B112
210B178
211B176
212B150
213B194
214B193
215B143
216B157
217B154
218B69
219B69
220B181
221B223
222B121
223B187
224B155
225B159
226B150
227B55
228B147
229B148
230B112
231B103
232B110
233B140
234B124
235B101
236B120
237B183
238B178
239B80
240B126
241B164
242B193
243B182
244B146
245B119
246B184
247B162
248B120
249B186
250B193
251B210
252B184
253B160
254B53
255B122
256B185
257B147
258B177
259B159
260B70
261B89
262B309
263B132
264B166
265B190
266B169
267B122
268B136
269B78
270B243
271B162
271B174
273B179
274B119
275B171
276B90
277B78
278B131
279B175
280B113
281B122
282B129
283B182
284B107
285B147
286B115
287B136
288B124
289B138
290B85
291B70
292B151
293B155
294B203
295B91
296B143
297B161
298B178
299B77
300B195
301B181
302B91
303B99
304B128
305B129
306B138
307B190
308B178
309B173
310B67
311B116
312B159
313B140
314B162
315B90
316B154
317B178
318B157
319B192
320B153
321B171
322B120
323B178
324B240
325B122
326B52
327B126
328B187
329B112
330B192
331B144
332B82
333B91
334B113
335B151
336B155
337B150
338B216
339B83
340B138
341B199
342B126
343B71
344B80
345B152
346B181
347B115
348B179
349B175
350B134
351B139
352B165
353B13
354B183
355B137
356B101
357B202
358B139
359B163
360B114
361B106
362B150
363B188
364B62
365B130
366B275
367B184
368B138
369B154
370B37
371B19
372B216
373B128
374B17
375B224
376B169
377B128
378B140
379B157
380B118
381B152
382B140
383B143
384B138
385B99
386B115
387B157
388B178
389B142
390B218
391B117
392B212
393B193
394B101
395B100
396B163
397B221
398B100
399B95
400B132
401B149
402B167
403B101
404B116
405B124
406B149
407B222
408B101
409B218
410B132
411B202
412B76
413B151
414B56
415B70
416B257
417B172
418B121
419B155
420B154
421B117
422B219
423B66
424B125
425B230
426B224
427B151
428B108
429B155
430B156
431B196
432B131
433B90
434B140
435B149
436B44
437B193
438B139
439B188
440B190
441B211
442B171
443B164
444B135
445B123
446B174
447B123
448B92
449B142
450B259
451B142
452B147
453B157
454B87
455B164
456B217
457B156
458B201
459B140
460B134
461B146
462B168
463B130
464B189
465B168
466B143
467B83
468B139
469B86
470B121
471B160
472B114
473B202
474B156
475B204
476B170
477B160
478B183
479B57
480B152
481B133
482B237
483B82
484B170
485B149
486B102
487B164
488B165
489B157
490B193
491B141
492B134
493B176
494B113
495B140
496B45
497B157
498B102
499B68
500B108
501B40
502B126
503B129
504B155
505B229
506B198
507B178
508B142
509B201
510B135
511B99
512B43
513B143
514B121
515B110
516B197
517B200
518B87
519B171
520B161
521B140
522B42
523B192
524B109
525B97
526B119
527B75
528B164
529B90
530B196
531B193
532B125
533B110
534B178
535B146
536B217
537B141
538B181
539B225
540B65
541B144
542B114
543B191
544B192
545B150
546B159
547B139
548B169
549B156
550B21
551B156
552B91
553B121
554B122
555B111
556B124
557B146
558B109
559B173
560B95
561B206
562B158
563B134
564B152
565B167
566B141
567B158
568B192
569B131
570B124
571B192
572B146
573B110
574B170
575B201
576B91
577B131
578B214
579B153
580B186
581B148
582B125
583B155
584B132
585B171
586B69
587B93
588B152
589B205
590B128
591B165
592B210
593B155
594B71
595B177
596B118
597B182
598B157
599B196
600B119
601B156
602B209
603B154
604B128
605B92
606B127
607B93
608B191
609B212
610B97
611B141
612B191
613B128
614B75
615B166
616B132
617B68
618B139
619B73
620B73
621B149
622B136
623B52
624B134
625B72
626B67
627B96
628B100
629B184
630B224
631B58
632B193
633B150
634B135
635B151
636B138
637B207
638B158
639B223
640B124
641B129
642B173
643B179
644B142
645B93
646B101
647B166
648B177
649B88
650B153
651B74
652B111
653B176
654B125
655B122
656B170
657B96
658B200
659B170
660B204
661B146
662B136
663B123
664B101
665B106
666B129
667B169
668B109
669B87
670B70
671B160
672B136
673B125
674B247
675B131
676B82
677B104
678B167
679B99
680B176
681B114
682B201
683B148
684B154
685B155
686B128
687B192
688B199
689B99
690B159
691B91
692B98
693B158
694B106
695B219
696B177
697B143
698B192
699B109
700B61
701B229
702B158
703B134
704B130
705B106
706B117
707B210
708B252
709B119
710B122
711B45
712B130
713B99
714B187
715B84
716B160
717B103
718B53
719B118
720B164
721B128
722B141
723B192
724B183
725B222
726B129
727B178
728B114
729B157
730B145
731B148
732B126
733B194
734B176
735B174
736B198
737B121
738B109
739B145
740B184
741B201
742B122
743B190
744B118
745B124
746B161
747B151
748B150
749B96
750B136
751B173
752B229
753B192
754B235
755B164
756B173
757B145
758B132
759B178
760B107
761B136
762B177
763B74
764B113
765B72
766B96
767B151
768B151
769B117
770B112
771B89
772B177
773B109
774B106
775B188
776B90
777B162
778B161
779B120
780B160
781B160
782B128
783B140
784B141
785B89
786B191
787B144
788B54
789B147
790B218
791B172
792B132
793B125
794B125
795B144
796B145
797B79
798B140
799B180
800B203
801B148
802B164
803B127
804B156
805B116
806B170
807B145
808B228
809B137
810B136
811B162
812B132
813B119
814B97
815B168
816B72
817B116
818B151
819B200
820B155
821B139
822B151
823B94
824B202
825B108
826B334
827B134
828B171
829B91
830B102
831B83
832B154
833B221
834B188
835B30
836B102
837B207
838B112
839B216
840B98
841B166
842B180
843B122
844B186
845B110
846B190
847B191
848B234
849B184
850B223
851B158
852B162
853B121
854B143
855B150
856B134
857B48
858B173
859B124
860B133
861B103
862B137
863B85
864B179
865B176
866B100
867B204
868B173
869B141
870B123
871B200
872B111
873B143
874B117
875B70
876B169
877B206
878B159
879B177
880B135
881B103
882B105
883B115
884B52
885B161
886B111
887B156
888B56
889B105
890B90
891B137
892B164
893B156
894B154
895B195
896B181
897B163
898B181
899B101
900B164
901B129
902B191
903B169
904B169
905B196
906B140
907B90
908B179
909B171
910B92
911B162
912B134
913B117
914B130
915B145
916B96
917B115
918B128
919B208
920B96
921B173
922B99
923B120
924B183
925B193
926B150
927B174
928B119
929B154
930B137
931B112
932B113
933B64
934B130
935B188
936B199
937B186
938B120
939B112
940B112
941B134
942B54
943B173
944B199
945B129
946B181
947B91
948B147
949B131
950B131
951B168
952B135
953B132
954B114
955B212
956B119
957B109
958B137
959B69
960B173
961B116
962B141
963B130
964B173
965B183
966B177
967B161
968B164
969B95
970B115
971B189
972B220
973B145
974B158
975B177
976B200
977B203
978B108
979B101
980B111
981B185
982B199
983B154
984B106
985B125
986B137
987B150
988B107
989B122
990B146
991B197
992B172
993B179
994B105
995B73
996B156
997B129
998B110
999B165
1000B208
1001B150
1002B92
1003B135
1004B126
1005B155

Podemos ver que se han reorganizado las filas de la base de datos. De hecho se han duplicado el número de filas (hemos ampliado dos variables) y ahora cada columna identifica claramente la información de un sujeto.

2.4 Análisis Descriptivo inicial

Esta sección muestra los procedimientos de análisis estadístico descriptivo para el estudio de una o dos variables de tipo numérico y/o categórico. Las situaciones que se plantean son:

  • Una variable de tipo factor.
  • Una variable de tipo numérico.
  • Dos variables categóricas.
  • Dos variables numéricas.
  • Una variable categórica y una variable numérica.

Este es el primer paso del EDA y sirve al investigador para plantear o responder las primeras preguntas de interés sobre sus datos. Para ilustrar los procedimientos utilizaremos el conjunto de datos storms de la librería nasaweather. Estos datos son un subconjunto de la base de datos de la NASA sobre los huracanes en el Atlántico Norte (NOAA). Los datos incluyen las posiciones y atributos de 198 tormentas tropicales, medidas cada seis horas durante la vida de la tormenta. Las variables registradas son:

  • name: Nombre de la tormenta
  • year, month, day: Año, mes y día del informe de la tormenta
  • hour: Hora del informe (en UTC)
  • lat, long: Latitud y longitud de la tormenta
  • pressure: Presión atmosférica en el centro de la tormenta (en milibares)
  • wind: Máxima velocidad sostenida de la tormenta (en nudos)
  • type: Clasificación de la tormenta (Tropical Depression, Tropical Storm, or Hurricane)
  • seasday: día de la temporada de tormentas
library(nasaweather)
# Guardamos los datos en un nuevo objeto
storm <- nasaweather::storms 
# Estructura de los datos
str(storm)

Dado que las variables year y month no vienen definidas como factores, el primer paso es convertirlas en factores. En este caso vamos a utilizar una versión diferente de la vista en el tema anterior para convertir varaibles enteras a factores.

# Primero creamos el factor año
storm$year_f <- factor(storm$year)
# Asignamos los niveles
levels(storm$year_f) <- as.character(1995:2000)
# Ahora el factor mes
storm$month_f <- factor(storm$month)
# Asignamos los niveles
levels(storm$month_f) <- c("June", "July", "August", "September", 
                           "October", "November", "December")
# Veamos como queda el banco de datos
str(storm)
## tibble [2,747 × 13] (S3: tbl_df/tbl/data.frame)
##  $ name    : chr [1:2747] "Allison" "Allison" "Allison" "Allison" ...
##  $ year    : int [1:2747] 1995 1995 1995 1995 1995 1995 1995 1995 1995 1995 ...
##  $ month   : int [1:2747] 6 6 6 6 6 6 6 6 6 6 ...
##  $ day     : int [1:2747] 3 3 3 3 4 4 4 4 5 5 ...
##  $ hour    : int [1:2747] 0 6 12 18 0 6 12 18 0 6 ...
##  $ lat     : num [1:2747] 17.4 18.3 19.3 20.6 22 23.3 24.7 26.2 27.6 28.5 ...
##  $ long    : num [1:2747] -84.3 -84.9 -85.7 -85.8 -86 -86.3 -86.2 -86.2 -86.1 -85.6 ...
##  $ pressure: int [1:2747] 1005 1004 1003 1001 997 995 987 988 988 990 ...
##  $ wind    : int [1:2747] 30 30 35 40 50 60 65 65 65 60 ...
##  $ type    : chr [1:2747] "Tropical Depression" "Tropical Depression" "Tropical Storm" "Tropical Storm" ...
##  $ seasday : int [1:2747] 3 3 3 3 4 4 4 4 5 5 ...
##  $ year_f  : Factor w/ 6 levels "1995","1996",..: 1 1 1 1 1 1 1 1 1 1 ...
##  $ month_f : Factor w/ 7 levels "June","July",..: 1 1 1 1 1 1 1 1 1 1 ...

A lo largo de cada una de las secciones siguientes se irán introduciendo las funciones y procedimientos necesarias para cada análisis en función de la variable o variables que se desean analizar.

2.4.1 Una variable factor

En esta sección se considera cómo explorar la distribución de una variable categórica. Se presentan las descriptivas básicas y visualizaciones que son apropiadas para las variables categóricas. Para ejemplificar los procedimientos utilizaremos la variable type que identifica el tipo de tormenta.

Explorar variables categóricas es generalmente más simple que trabajar con variables numéricas porque tenemos menos respuestas posibles. La primera pregunta que nos debemos plantear es is la variables categórica es de tipo nominal u ordinal. Esto tiene un efecto relevante a la hora de presentar y visualizar la información. La variable type es una variable categórica de tipo ordinal debido a que las tormentas son clasificadas según su virulencia.

2.4.1.1 Resúmenes numéricos

Cuando calculamos resúmenes de variables categóricas, intentamos describir la distribución muestral de la variable mediante el recuento de ocurrencias de cada una de las posibles respuestas de la variable. Estos recuentos es lo que denominamos en estadística frecuencias absolutas. Necesitamos entender qué categorías son comunes y cuáles son raras. Asociado a dichas frecuencias absolutas podemos obtener las frecuencias relativas, o más frecuentemente los porcentajes de cada una de las posibles categorías de la variable.

Si \(F_i\) es la frecuencia absoluta de la categoría \(i\) de la variable y \(n\) es el tamaño de la muestra, se define la frecuencia relativa de la categoría \(i\) (\(f_i\)) como:

\[\begin{equation} f_i =\frac{F_i}{n} \tag{2.1} \end{equation}\]

El porcentaje de la categoría \(i\) es simplemente \(100 * f_i\). La forma más sencilla para obtener la tabla de frecuencias absoluta asociada con una variable categórica es la función table().

table(storm$type)
## 
##       Extratropical           Hurricane Tropical Depression      Tropical Storm 
##                 412                 896                 513                 926

Para obtener los porcentajes en lugar de los conteos podemos utilizar le código siguiente

type_counts <- table(storm$type)
round(type_counts / sum(type_counts),2) # Redondeamos a dos decimales
## 
##       Extratropical           Hurricane Tropical Depression      Tropical Storm 
##                0.15                0.33                0.19                0.34

Sin embargo, hay otra opción un poco más compleja pero que nos servirá de utilidad para el resto de esta unidad y que pasamos a mostrar a continuación. Es una combinación del operador de anidamiento %>%, de la función de agrupación (group_by()), de la función de resumen (summarise()), y de la función de conteos (n()).

# banco de datos
tabla_tipo <- storm %>%  # agrupamos por la variable factor
  group_by(type) %>%     # resumimos contando el número de casos de cada nivel del factor
  summarise(n=n())       # Para calcular los porcentajes
mutate(tabla_tipo,percent=round(100*n/sum(n),2))
Tabla 2.3:
typenpercent
Extratropical41215  
Hurricane89632.6
Tropical Depression51318.7
Tropical Storm92633.7

Aunque esta forma es más costosa cuando tenemos únicamente una variable nos resultará de más utilidad cuando deseemos realizar análisis que involucren un mayor número de variables.

Podemos ver que mayoritariamente se han producido Tormentas Tropicales (33.71%) y Huracanes (32.62%). Estos dos tipos suman más de dos tercios de los ecentos registrados. Por contra los eventos menos abundantes han sido las Depresiones Tropicales (18.67%) y las Extratropicales (15.00%).

Las funciones más habituales que se utilizan con summarise() son:

  • Localización: mean() (media), median() (mediana)
  • Escala: sd() (desviación típica), IQR() (rango intercuartílico)
  • Rango: min() (mínimo), max() (máximo), quantile() (cuantil)
  • Posición: first() (primero), last() (último), nth() (posición n-ésima)
  • Conteo: n() (número de casos), n_distinct() (número de casos distintos)

La mayoría se usan exclusivamente para variables de tipo numérico.

2.4.1.2 Visualización gráfica

En este apartado veremos como representar los datos de los conteos de una variable categórica mediante la función ’ggplot`. Esta función permite realizar casi cualquier tipo de gráfico que podamos imaginar. En este punto vamos a ir presentando diferentes parámetros de dicha función para ir familiarizándonos con su uso.

2.4.1.2.1 Gráfico barras

La herramienta gráfica más común utilizada para resumir una variable categórica es un gráfico de barras. Un gráfico de barras (o gráfico de barras) es un gráfico que presenta resúmenes de datos agrupados con barras rectangulares. La longitud de las barras es proporcional a los valores que representan. Al resumir una sola variable categórica, la longitud de las barras debe mostrar los recuentos brutos o las proporciones de cada categoría.

Para realizar este gráfico con la función ggplotnecesitamos identificar el conjunto de datos sobre el que vamos a trabajar y la variable que queremos representar:

# Configuramos el gráfico identificando los datos y la variable de interés
bar_plt <- ggplot(storm, aes(x = type)) 
bar_plt <- bar_plt + geom_bar() # Seleccionamos el tipo gráfico
bar_plt                         # Representamos el gráfico
Gráfico de barras del tipo de tormenta.

Figura 2.1: Gráfico de barras del tipo de tormenta.

Podemos personalizar este gráfico de barras si es necesario con funciones como xlab y ylab, y configurando varias propiedades dentro de geom_bar. Por ejemplo:

# Retocamos las barras para que aparezcan en azul y con un ancho inferior
# En este caso no almacenamos el gráfico sino que lo ejecutamos directamente
ggplot(storm, aes(x = type)) + 
  geom_bar(fill = "blue", width = 0.7) + 
  xlab("Tipo de Tormenta") + ylab("Número de observaciones")
Gráfico de barras del tipo de tormenta (versión 2).

Figura 2.2: Gráfico de barras del tipo de tormenta (versión 2).

Como podemos ver tanto en las tablas obtenidas como en los dos gráficos precedentes la escala del tipo de tormenta no está ordenada, es decir, no la tenemos graduada por la relevancia de la tormenta. Veamos como podemos hacer esto e integrarlo en el gráfico:

# Creamos un vector con el orden predefinido
ords <- c("Tropical Depression", "Extratropical", "Tropical Storm", "Hurricane")
# Generamos el gráfico indica que el eje x tiene escala dada por el vector ordenado
ggplot(storm, aes(x = type)) + 
  geom_bar(fill = "blue", width = 0.7) + 
  scale_x_discrete(limits = ords) +
  xlab("Tipo de Tormenta") + ylab("Número de observaciones")
Gráfico de barras del tipo de tormenta (versión 3).

Figura 2.3: Gráfico de barras del tipo de tormenta (versión 3).

Ahora el gráfico si está ordenado con la escala adecuada y resulta más fácil cuantificar la relevancia de las tormentas más importantes. También podemos intercambiar las filas por las columnas para una mejor visualización de las etiquetas de la variable categórica. Para ello utilizamos el parámetro coord_flip():

ggplot(storm, aes(x = type)) + 
  geom_bar(fill = "blue", width = 0.7) + 
  scale_x_discrete(limits = ords) +
  coord_flip() + 
  xlab("Tipo de Tormenta") + ylab("Número de observaciones")
Gráfico de barras del tipo de tormenta (versión 4).

Figura 2.4: Gráfico de barras del tipo de tormenta (versión 4).

Por último utilizamos la función theme_bw() para configurar un fondo blanco para el gráfico. Otras posibilidades para los temas son theme_classic(), theme_dark(), theme_grey(), theme_light().

ggplot(storm, aes(x = type)) + 
  geom_bar(fill = "blue", width = 0.7) + 
  scale_x_discrete(limits = ords) +
  coord_flip() + 
  xlab("Tipo de Tormenta") + ylab("Número de observaciones")+
  theme_bw() 
Gráfico de barras del tipo de tormenta (versión 5).

Figura 2.5: Gráfico de barras del tipo de tormenta (versión 5).

En lugar de representar los contesos podemos visualizar los porcentajes asociados a cada categoría en lugar de los conteos haciendo uso de la variable ..prop.. en la configuración de geom_bar(). Se debe modificar la escala de la varaible para indicar que estamos representando porcentajes (labels = scales::percent):

ggplot(storm, aes(x = type)) + 
  geom_bar(aes(y = ..prop.. , group = 1),fill = "blue", width = 0.7) + 
  scale_y_continuous(labels = scales::percent) +
  coord_flip() + 
  xlab("Tipo de Tormenta") + ylab("Porcentaje")+
  theme_bw() 
Gráfico de barras del porcentaje de cada tipo de tormenta.

Figura 2.6: Gráfico de barras del porcentaje de cada tipo de tormenta.

2.4.2 Una variable numérica

En esta sección se considera cómo explorar la distribución de una variable numérica Se presentan las descriptivas básicas y visualizaciones que son apropiadas para las variables de este tipo. Para ejemplificar los procedimientos utilizaremos las variables wind y pressure.

2.4.2.1 Resúmenes numéricos

Hasta ahora hemos estado describiendo las propiedades de las distribuciones de muestra en términos muy generales, usando frases como “valores más comunes” y “el rango de los datos” sin decir realmente lo que queremos decir. Los estadísticos han ideado términos específicos para describir este tipo de propiedades, así como diferentes estadísticas descriptivas para cuantificarlas. Los dos que más importan son la tendencia central y la dispersión:

  • Una medida de tendencia central describe un valor típico (‘central’) de una distribución de datos. La medida de localización más extendida es la media aritmética de una muestra. Hay muchas medidas diferentes de tendencia central, cada una con sus propios pros y contras. Entre estos, la mediana es la que se usa con mayor frecuencia en los análisis exploratorios ya que es le valor que nos divide la muestra de dos partes iguales situando el 50% de los datos a cada lado de ese valor.
  • Una medida de dispersión describe cómo se distribuye una distribución. Las medidas de dispersión cuantifican la variabilidad o dispersión de una variable con respecto al promedio de los datos. Si una distribución está más dispersa que otra, significa que, en cierto sentido, abarca una gama más amplia de valores. Lo que esto significa en la práctica depende del tipo de medida con la que estamos trabajando. Las medidas de dispersión más habituales son la varianza y su raíz cuadrada, la desviación estándar.
2.4.2.1.1 Medidas de tendencia central

Hay dos estadísticos que se utilizan generalmente para describir la tendencia central de la distribución de los datos muestrales de un variable numérica. De ahora en adelante denotamos por \(n\) al tamaño muestral y \(x_1, x_2,...,x_n\) los valores muestrales de la variable que deseamos estudiar.

La media muestral es la medida de tendencia muestral por excelencia. La definición matemática de la media muestral viene dada por: \[\begin{equation} \bar{x} = \frac{\sum_{i=1}^n x_i}{n} \tag{2.2} \end{equation}\]

Para obtener la media utilizamos la función mean()

mean(storm$wind)
## [1] 54.68329
mean(storm$pressure)
## [1] 989.8238

Esto nos dice que la media de la velocidad del viento es de 55 mph y que la media de la presión es de 989.82 milibares. ¿Como podemos interpretar esos resultados?

Una limitación de la media aritmética es que se ve afectada por la forma de la distribución de los datos. Es muy sensible a los extremos de una muestra. Esta es la razón por la cual, por ejemplo, no tiene mucho sentido mirar el ingreso medio de los trabajadores en un país para tener una idea de lo que gana una persona “típica.” La distribución del ingreso es muy asimétrica, y los pocos que tienen la suerte de ganar salarios muy buenos tienden a cambiar la media hacia arriba y superar cualquier cosa que sea realmente “típica.” La media de la muestra también se ve fuertemente afectada por la presencia de ‘valores atípicos’ o valores extremos, es decir, valores inusualmente grandes o pequeños en una muestra.

Debido a que la media muestral es sensible a la forma de una distribución y la presencia de valores atípicos, a menudo se prefiere una segunda medida de tendencia central: la mediana de la muestra. La mediana de una muestra es el número que separa los datos en dos subgrupos (la mitad superior de la mitad inferior). Podemos calcular la mediana muestral en R con la función median():

median(storm$wind)
## [1] 50
median(storm$pressure)
## [1] 995

Estos resultados indican que el 50% de de los registros muestran una valor de viento inferior a 50 mph. De la misma forma el 50% de los datos muestran una valor de la presión inferior a 995 milibares.

Otras medidas de localización son el mínimo, el máximo y los percentiles. Los percentiles son los valores que dividen en la muestra según el valor del percentil solicitado. Si solicitamos el percentil 20, se separa la muestra en dos subconjuntos dejando el 20% en un grupo y e 80% en el otro. Los percentiles más habituales son lo denominados primer y tercer cuartil que corresponden a los percentiles 25 y 75 respectivamente. Para obtener el percentil asociado a una variable numérica podemos hacer uso de la función quantile(). Para ver como se debe utilizar es útil consultar la ayuda de dicha función help(quantile).

2.4.2.1.2 Medidas de dispersión

Hay muchas maneras de cuantificar la dispersión de un conjunto de datos muestrales de una variable numérica. Los valores más importantes desde el punto de vista estadístico son la varianza muestral y la desviación estándar. La varianza muestral \(s^2\) es “la suma de las desviaciones cuadradas” (es decir, las diferencias) de cada observación con respecto a la media de la muestra, dividida por el tamaño de la muestra menos uno. La desviación típica es la raíz cuadrada de la varianza muestral. Las definiciones matemáticas de ambas cantidades son: \[\begin{equation} s^2 = \frac{\sum_{i=1}^n (x_i-\bar{x})^2}{n-1} \tag{2.3} \end{equation}\]

\[\begin{equation} s = \sqrt{s^2} \tag{2.4} \end{equation}\]

Las funciones de R para calcular ambas cantidades son var() para la varianza y sd() para la desviación típica.

var(storm$wind);sd(storms$wind)
## [1] 668.1444
## [1] 25.84849
var(storm$pressure);sd(storms$pressure)
## [1] 349.4912
## [1] 18.69468

¿Qué significa ese número en realidad? Las variaciones son siempre no negativas. Una pequeña varianza indica que las observaciones tienden a ser cercanas a la media (y una a la otra), mientras que una alta varianza indica que las observaciones están muy dispersas. Una varianza de cero solo ocurre si todos los valores son idénticos. Sin embargo, es difícil interpretar si una varianza muestral es realmente “pequeña” o “grande” porque el cálculo involucra desviaciones al cuadrado. Por ejemplo, cambiar la escala de medición de una variable por 10 implica un cambio de 100 veces (102) en la varianza.

La varianza es una cantidad importante en las estadísticas que aparece una y otra vez. Muchas herramientas estadísticas comunes usan cambios en la varianza para comparar formalmente qué tan bien diferentes modelos describen un conjunto de datos. Sin embargo, es muy difícil interpretar las variaciones, por lo que rara vez las utilizamos en el trabajo exploratorio. Para expresar la variabilidad en la misma escala de la variable original utilizamos la desviación típica. En este caso se puede observar una mayor variabilidad en la variable presión atmosférica (desviación típica de 25.84 milibares) que en la variable de viento (18.69 mph).

La desviación estándar de la muestra no está exenta de problemas. Al igual que la media muestral, es sensible a la forma de la distribución de los datos y a la presencia de valores atípicos. Una medida de dispersión más robusta para este tipo de características es el rango intercuartílico, definida como la diferencia entre el percentil 75 (tercer cuartil) y el percentil 25 (primer cuartil):

\[\begin{equation} IQR = Q_3 - Q_1 \tag{2.5} \end{equation}\]

Obviamente, cuanto más dispersos estén los datos, mayor será el IQR. La razón por la que preferimos usar IQR para medir la dispersión es que solo depende de los datos en el “medio” de una distribución de muestra. Esto lo hace robusto a la presencia de valores atípicos. Podemos usar la función IQR() para calcular el rango intercuartílico:

IQR(storm$wind)
## [1] 35
IQR(storm$pressure)
## [1] 24

La última medidad de dispersión que veremos es el coeficiente de variación. Esta medida es una de las más habituales y se obtiene a partir de la media y desviación típica muestral como: \[\begin{equation} CV = \frac{s}{\bar{x}} \tag{2.6} \end{equation}\]

Su fórmula expresa la desviación estándar como porcentaje de la media aritmética, mostrando una interpretación relativa del grado de variabilidad, independiente de la escala de la variable, a diferencia de la desviación típica o estándar. De esta forma, valores bajos del coeficiente de variación expresan menor variabilidad, lo que resulta de utilidad cuando deseamos comparar la variabilidad de dos muestras independeintemente de su media. El mayor problema es que sólo puede ser usado cuando la media muestral es positiva.

2.4.2.1.3 Resúmenes conjuntos

Aunque podemos ir calculando cada una de las medidas de localización y dispersión vistas anteriormente, en la práctica nos resulta más útil obtenerlas todas de una vez. Existen diferentes funciones que nos permiten obterner estos análisis descriptivos. La primera de ellas es la función summary() que nos porporciona el mínimo, máximo, media, mediana y los percentiles 25 y 75. Sin embargo, no nos porporciona ninguna de las medidas de varaibilidad usuales. En nuestro ejemplo

summary(storm$wind)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   15.00   35.00   50.00   54.68   70.00  155.00
summary(storm$pressure)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   905.0   980.0   995.0   989.8  1004.0  1019.0

Se pude ver que el 25% de las observaciones muestran una valor de viento inferior a 35mph y un 25% un valor de viento superior a 70mph. Con respecto a la presión atmosférica tenemos que el 25% de las observaciones tienen un valor inferior a 980 milibares, y un 25% tienen un valor superior a 1004 milibares.

Otra función que nos porporciona medidas conjuntas es estat() de la librería pubh. Esta función nos porporciona el número de casos, el mínimo, el máximo, la media, la mediana, la desviación típica, y el coeficiente de variación.

# Etiquetamos las variables
storm = storm %>% 
  var_labels(wind = 'Wind speed (in knots)', 
             pressure = 'Air pressure (in mbar)')
# Análisis descriptivos
estat(~ wind, data = storm)
Tabla 2.4:
NMin.Max.MeanMedianSDCV
Wind speed (in knots)2.75e+031515554.75025.90.47
estat(~ pressure, data = storm)
Tabla 2.4:
NMin.Max.MeanMedianSDCV
Air pressure (in mbar)2.75e+039051.02e+0399099518.70.02

2.4.2.2 Visualización gráfica

En este apartado veremos como representar los datos de los conteos de una variable categórica mediante la función ’ggplot`. Esta función permite realizar casi cualquier tipo de gráfico que podamos imaginar. En este punto vamos a ir presentando diferentes parámetros de dicha función para ir familiarizándonos con su uso.

2.4.2.2.1 Gráfico barras

El gráfico por excelencia para una variable de tipo numérico es el denominado histograma. El histograma es una representación mediante barras de la distribución de los datos. Para construir las barras se divide el rango de la variable numérica en un conjunto fijo de intervalos disjuntos y se contabiliza el número de datos que quedan dentro de cada uno de ellos (altura del gráfico de barras). Es un gráfico muy interesante porque representa de forma bastante precisa, ajustando el número de intervalos, la distribución del conjunto de datos pudiéndose observar su dispersión y/o asimetria.

Para realizar este gráfico utilizamos parámetros específicos dentro de la función ggplot() a partir de geom_histogram().

ggplot(storm, aes(x = pressure)) +
   geom_histogram()
Histograma de la presión atmosférica.

Figura 2.7: Histograma de la presión atmosférica.

Podemos ver que la mayoría de los datos se sitúan por encima de 915 milibares, hay una clara asimetría hacia los valores más grandes y existe una gran dispersión entre en el conjunto de valores observados.

Veamos como introducir diferentes parámetros en el gráfico anterior. el más importante es el que hace referencia a los intervalos asociado con el histograma (parámetro binwith)

ggplot(storm, aes(x = pressure)) + 
  geom_histogram(binwidth = 8, fill = "steelblue") + 
  xlab("Air pressure (in mbar)") + ylab("Frequency")
Histograma de la presión atmosférica (modificando binwidth).

Figura 2.8: Histograma de la presión atmosférica (modificando binwidth).

Veamos ahora el histograma de la variable wind

ggplot(storm, aes(x = wind)) + 
  geom_histogram(binwidth = 8, fill = "steelblue") + 
  xlab("Wind speed (in knots)") + ylab("Frequency")
Histograma de la velocidad del viento.

Figura 2.9: Histograma de la velocidad del viento.

El otro gráfico habitual para una variable de tipo numérico es el llamado gráfico de cajas. En este gráfico se representa mediante una caja la media (linea central de la caja), el percentil 75 (línea superior de la caja), y el percentil 25 (linea inferior de la caja). También se representan el valor máximo (percentil 75 + 1.5 IQR) y mínimo (percentil 25 - 1.5 IQR), así como los caracterizados como valores extremos (punto fuera de la caja). Veamos como realizar este gráfico mediante el parámetro geom_boxplot().

ggplot(storm, aes(x = factor(1),y = pressure)) +
   geom_boxplot()
Gráfico de cajas de la presión atmosférica.

Figura 2.10: Gráfico de cajas de la presión atmosférica.

Añadimos parámetros (título de ejes, color caja, selección de valores extremos, y fondo blanco)

ggplot(storm, aes(x = factor(1), y = pressure)) +
   geom_boxplot(fill = "orange", outlier.colour = "red", outlier.shape = 1) +
   scale_x_discrete(name = " ") + scale_y_continuous(name = "Air pressure (in mbar)") +
   theme_bw()
Gráfico de cajas de la presión atmosférica (versión 2).

Figura 2.11: Gráfico de cajas de la presión atmosférica (versión 2).

Podemos ver que la media se sitúa muy próxima a los 1000 mbar y la gran cantidad de valores extremos en la parte baja de la distribución. Además la caja es muy estrecha indicando la poca variabilidad en los datos, lo que viene corroborado también por la proximidad de los percentiles 25 y 75.

Ahora el gráfico para la variable wind

ggplot(storm, aes(x = factor(1),y = wind)) +
   geom_boxplot(fill = "orange",outlier.colour = "red", outlier.shape = 1) +
   scale_x_discrete(name = " ") + scale_y_continuous(name = "Wind speed (in knots)") +
   theme_bw()
Gráfico de cajas de la velocidad del viento.

Figura 2.12: Gráfico de cajas de la velocidad del viento.

¿Cómo interpretamos este gráfico?

2.4.3 Dos variables categóricas

Explorar numéricamente las asociaciones entre pares de variables categóricas no es tan simple como el caso de una variable. La pregunta general que debemos abordar es, “¿las diferentes combinaciones de categorías parecen estar sub o sobre representadas?” Necesitamos entender qué combinaciones son comunes y cuáles son raras. Lo más simple que podemos hacer es construir una tabulación cruzada del número de ocurrencias de cada combinación de niveles de ambas variables. La tabla resultante se llama tabla de contingencia.

En cuanto a la representación gráfica la opción más habitual pasa por representar los conteos mediante gráficos de barras que representan de forma conjunta la información de ambas variables.

Para ejemplificar los cálculos y gráficos utilizaremos las variables month_f (mes como factor) y type. En primer lugar etiquetamos las variables.

# Etiquetamos las variables
storm = storm %>% 
  var_labels(month_f = 'Month', 
             type = 'Storm category')

2.4.3.1 Resúmenes numéricos

El resumen numérico habitual para este tipo de situación es la tabla de contigencia (tabla de doble entrada) que nos porporciona los conteos o coincidencias entre los niveles de cada factor. Obtener la tabla completa (frecuencias y porcentajes) puede ser una faena algo pesada utilizando las funciones habituales. En nuestro caso utilizaremos la función cross_tab de la librería pubh. Dicha función nos porpociona la tbala de doble entrada con los conteos y los porcentajes marginales por columnas. Veamos su uso en el banco de datos.

table(storm$type, storm$month_f)
##                      
##                       June July August September October November December
##   Extratropical         27   38     23       149     129       42        4
##   Hurricane              3   31    300       383     152       25        2
##   Tropical Depression   22   59    150       156      84       42        0
##   Tropical Storm        31  123    247       259     204       61        1

Esta tabla nos permite analizar las concidencias entres los fatores estudiados (conteos), así como la relevancia de cada tipo de tormenta a los largo de los meses estudiados (porcentajes marginales por columnas). Por ejemplo, podemos ver que el perido más activo de huracanes es el comprendido entre los meses de agosto a octubre.

En este caso los porcentajes marginales nos revelan que tipo de tormenta es más habitual dentro de cada mes de los analizados. Por ejemplo, en el mes de agosto el tipo de tormenta más habitual son los huracanes con un 40.1%, lo que representa casi la mitad de los observado durante ese mes.

2.4.3.2 Visualización gráfica

Los gráficos de barras se pueden usar para resumir la relación entre dos variables categóricas. La idea básica es producir una barra separada para cada combinación de categorías en las dos variables. La longitud de estas barras es proporcional a los valores que representan, que son los recuentos brutos o las proporciones en cada combinación de categorías. Esta es la misma información que se muestra en una tabla de contingencia. El uso de ggplot2 para mostrar esta información no es muy diferente de producir un gráfico de barras para resumir una única variable categórica.

Tomamos las variables type y year_f para mostrar su funcionamiento. Ordenamos la variable type para mostrar los gráficos por orden de importancia de la tormenta. En primer lugar realizamos el gráfico de barras apiladas.

# Creamos un vector con el orden predefinido
ords <- c("Tropical Depression", "Extratropical", "Tropical Storm", "Hurricane")
# Generamos el gráfico indica que el eje x tiene escala dada por el vector ordenado
ggplot(storm, aes(x = type, fill = year_f)) + 
  geom_bar() + 
  scale_x_discrete(limits = ords) +
  xlab("Storm category") + ylab("Frequancy") 
Gráfico de barras apiladas para tipo de tormenta versus año.

Figura 2.13: Gráfico de barras apiladas para tipo de tormenta versus año.

En este caso cada tipo de tormenta tiene su propia barra, y cada barra se ha dividido en diferentes segmentos de colores, cuya longitud está determinada por el número de observaciones asociadas con cada año. Podemos apreciar si para un mismo tipo de tormenta la ocurrencia de un tipo de tormenta es similar o no. Por ejemplo, para los huracanes podemos apreciar que los años 1996, 1998, 1999, y 2000 tienen un número similar de ocurrencias.

Un problema con este tipo de gráfico es que puede ser difícil detectar asociaciones entre las dos variables categóricas. Si queremos saber cómo están asociados, a menudo es mejor trazar los recuentos para cada combinación de categorías una al lado de la otra. Este gráfico se denomina gráfico de barras agrupado. Utilizamos la opción dodge en la función geom_bar para poder realizar esta versión:

ggplot(storm, aes(x = type, fill = year_f)) + 
  geom_bar(position = "dodge") + 
  scale_x_discrete(limits = ords) +
  labs(x = "Storm category", y = "Frequancy", fill = "Storm category")
Gráfico de barras agrupado para el tipo de tormenta versus año.

Figura 2.14: Gráfico de barras agrupado para el tipo de tormenta versus año.

¿Qué ventajas o desventajas aprecias en este gráfico frente al de barras apiladas?

Alternativamente podríamos realizar el gráfico de porcentahjes en lugar de los conteos. Hacemos uso de la función ..prop.. e indicamos la agrupación por la variable year_f:

ggplot(storm, aes(x = type, fill = year_f)) + 
  geom_bar(aes(y = ..prop.. , group = year_f),position = "dodge") + 
  scale_y_continuous(labels = scales::percent) +
  labs(x = "Storm category", y = "Percent", fill = "Storm category")
Gráfico de barras agrupado (porcentjes) para el tipo de tormenta versus año.

Figura 2.15: Gráfico de barras agrupado (porcentjes) para el tipo de tormenta versus año.

Otra opción es realizar un mapa de intensidad de cada una de las combinaciones e ambos factores. Utilizamos la función geom_tile() a partir los conteos conjuntos para ambas variables con la opción count() que se almacenan en la variable temporal n.

storm %>%
    count(type,year_f) %>%
    ggplot(mapping = aes(x = type, y = year_f)) + 
        geom_tile(mapping = aes(fill = n)) + 
        scale_x_discrete(limits = ords) +
        labs(x = "Storm type", y = "Year", fill = "n")
Mapa de intensidad para el tipo de tormenta versus año.

Figura 2.16: Mapa de intensidad para el tipo de tormenta versus año.

En este caso las casillas en tonos más claros corresponden con las combinaciones de niveles con una mayor ocurrencia. Las más abundantes se concentran en 1995 y los tipos de tormenta más graves. Por otro lado el año 1997 es el que ha registrado menor número de tormentas.

2.4.4 Categórica vs Numérica

El objetivo en este tipo de situaciones es comparar cada una de las distribuciones de la variable numérica que surgen al segmentar los valores por cada uno de los niveles de la variable categórica. Tenemos tantas conjuntos de datos como niveles del facgor hemos observado.

2.4.4.1 Resúmenes numéricos

Los resúmenes numéricos se pueden construir tomando las diversas ideas que hemos explorado para las variables numéricas (medias, medianas, etc.) y aplicándolas a subconjuntos de datos definidos por los valores de la variable categórica. Sin embargo, podemos hacer uso de la función estat() para simplicar este trabajo. para ejemplificar su uso utilizamos la variable type como categórica y las variables wind y pressure como numéricas.

storm$type <- as.factor(storm$type)
# Simplificamos las etiquetas de las variables
storm = storm %>% 
  var_labels(wind = 'Wind', 
             pressure = 'Air pressure')
# Análisis descriptivos
estat(~ wind|type, data = storm)
Tabla 2.5:
typeNMin.Max.MeanMedianSDCV
WindExtratropical412158040.14013.2 0.33
Hurricane8966515584.78018.8 0.22
Tropical Depression513203027.4303.520.13
Tropical Storm9263512047.34511.1 0.23
estat(~ pressure|type, data = storm)
Tabla 2.5:
typeNMin.Max.MeanMedianSDCV
Air pressureExtratropical4129501.02e+03994       996       14.2 0.01
Hurricane8969051.00e+03970       974       16.9 0.02
Tropical Depression5139821.02e+031.01e+031.01e+033.9 0   
Tropical Storm9269351.01e+03998       1e+03       8.950.01

Se puede ver como el tipo Huracanes tiene la media más alta de velocidad del viento y la más baja de presión atmosférica. Además en ambos casos la variabilidad observada es la mayor de todos los tipos de tormenta. La depresión tropical es justo el caso contrario. Evidentemente los datos observados corresponden con la clasificación de tormenta establecida desde el inicio. ¿Qué otras conclusiones podemos obtener? ¿qué tipo de tormenta muestra una mayor variabilidad?

2.4.4.2 Visualización gráfica

Para la visualización gráfica de las relaciones entre una variable categórica y una numérica tenemos diferentes opciones: gráfico de densidad, gráfico de cajas, y gráficos comparativos matriciales.

El gráfico de densidad representa la distribución del conjunto de datos muestrales. Con este gráfico se puede apreciar claramente el rango de valores y su concentración (altura de la curva de densidad). Para su obtención utilizamos la opción geom_density() donde sólo debemos fijar el parámetro de suavizado, bw, que nos indica el grado de información que debemos utilizar para obtener dicha densidad. Valores pequeños dan curvas poco suavizadas y valores grandes dan curva suavizadas. Siempre es necesario un pequeño ajuste para obtener el valor más adecuado. Con este gráfico resulta muy fácil comparar el comportamiento de los diferentes grupos.

Comenzamos con la variable wind:

ggplot(storm, aes(x = wind)) + 
  geom_density(aes(colour = type), bw = 3, na.rm = TRUE) + 
  labs(x = "Wind speed (in knots)", y = "Density") 
Gráficos de densidades de la velocidad del viento por tipo de tormenta.

Figura 2.17: Gráficos de densidades de la velocidad del viento por tipo de tormenta.

# la opción na.rm elimina los valores pérdidos.

El resultado son cuatro curvas de densidad (una por cada top de tormenta) donde los más destacable es que el rango de valores posibles para la velocidad del viento es sólo diferente para el tipo huracanes, ya que su curva de densidad se encuentra desplazada respecto del resto de densidades. También se puede ver que las depresiones tropicales tienen una menor dispersión (menor rango de valores) los que provoca que su curva sea más puntiaguda. Cuanto mayor sea la dispersión mas amplia sera la densidad obtenida. Si la densidad es simétrica la media se sitúa en el punto medio, mientras que el valor asociado con el punto más alto de la densidad es lo que denominamos moda.

Ahora con la variable presión atmosférica:

ggplot(storm, aes(x = pressure)) + 
  geom_density(aes(colour = type), bw = 3, na.rm = TRUE) + 
  labs(x = "Air pressure (in knots)", y = "Density") 
Gráficos de densidades de la presión atmosférica por tipo de tormenta.

Figura 2.18: Gráficos de densidades de la presión atmosférica por tipo de tormenta.

El comportamiento de la variable presión atmosférica es muy similar al de la velocidad del viento pero en la parte izquierda del rango de valores. Los huracanes tienen la menor presión atmosférica y se distinguen del resto de tipos de tormenta. También muestra una mayor variabilidad que el resto de tipos.

La visualización más común para explorar las relaciones entre una variable categórica y otra numérica es el diagrama de cajas. Cada diagrama de caja consiste en:

  • Una casilla que se extiende desde el percentil 25 de la distribución hasta el percentil 75, una distancia conocida como rango intercuartílico (IQR). En el medio del recuadro hay una línea que muestra la mediana, es decir, el percentil 50 de la distribución. Estas tres líneas le dan una idea de la extensión de la distribución y si la distribución es simétrica o no respecto a la mediana o sesgada hacia un lado.
  • Puntos visuales que muestran observaciones que caen más de 1,5 veces el IQR desde cualquier borde de la caja. Estos puntos remotos son inusuales, por lo que se representan de forma individual.
  • Una línea (o bigote) que se extiende desde cada extremo de la caja y va al el punto más lejano no atípico en la distribución.

Veamos los ejemplos:

ggplot(storm, aes(x = type, y = wind)) + 
  geom_boxplot() + 
  scale_x_discrete(limits = ords) +
  labs(x = "Storm category", y = "Wind speed (in knots)") 
Gráficos de cajas de la velocidad del viento por tipo de tormenta.

Figura 2.19: Gráficos de cajas de la velocidad del viento por tipo de tormenta.

En este tipo de gráficos se esta interesado en dos aspecto fundamentales: * Estudiar la variabilidad dentro de cada grupo viendo la altura de la caja (IQR). * Comparar el comportamiento de cada grupo observando si las cajas quedan a alturas superpuestas.

En este caso podemos ver que la variabilidad más grande se produce en el tipo huracanes y la más pequeña en las depresiones tropicales. Se aprecian diferencias entre las variabilidades de los grupos. Por otro lado, las cajas correspondientes a las tormentas extra tropicales y tormentas tropicales quedan a una misma altura indicando que tienen valores similares para la velocidad del viento. Este gráfico nos da unas primeras indicaciones claras para los procedimientos de comparaciones de medias que estudiaremos más adelante.

ggplot(storm, aes(x = type, y = pressure)) + 
  geom_boxplot() + 
  scale_x_discrete(limits = ords) +
  labs(x = "Storm category", y = "Air pressure (in mbar)") 
Gráficos de cajas de la presión atmosférica por tipo de tormenta.

Figura 2.20: Gráficos de cajas de la presión atmosférica por tipo de tormenta.

En este caso observamos que los tipos extra tropical y Huracanes muestran variabilidades similares, mientras que los otros dos tipos también muestran variabilidades similares. En cuanto a la comparación de los grupos se observa que el único con un comportamiento diferente son los huracanes. Los otros tres tipos muestran cajas que se podrías solapar mostrando una mayor igualdad en los valores de presión atmosférica.

Los gráficos matriciales o de facetas permiten representar mediante múltiples gráficos la información de una variable numéricas con respecto a los niveles de la variable categórica. Se pretende de esta forma comprobar la forma de la distribución de los datos de forma similar al gráfico de densidad pero realzando un gráfico para cada nivel. Aunque resultan más útiles cuando trabajamos con más de dos variables, se introducen aquí para ir conociendo su funcionamiento en ejemplos sencillos.

Comenzamos realizando un histograma independiente. Para que resulte más fácil visualizar el gráfico introducimos un orden asociado con los valores de la variable numérica, comenzando con el nivel que tiene valores en esa variable más pequeños, y finalizando con la que tiene los valores más grandes.

# Creamos un nuevo factor ordenado de acuerdo a la variable que estamos midiendo
storm$type2 <- reorder(storm$type, storm$wind)
# Creamos el gráfico
ggplot(storm, aes(x = wind))  +
  geom_histogram(binwidth = 5) + 
  xlab("Wind speed (in knots)") +
  ylab("Frequency") +
  facet_wrap(~ type2, ncol = 1)
Gráficos matricial de velocidad del viento por tipo de tormenta

Figura 2.21: Gráficos matricial de velocidad del viento por tipo de tormenta

También podríamos realizar el gráfico de densidad

# Creamos el gráfico
ggplot(storm, aes(x = wind))  +
  geom_density(bw = 3) + 
  xlab("Wind speed (in knots)") +
  ylab("Density") +
  facet_wrap(~ type2, ncol = 1)
Gráficos matricial de velocidad del viento por tipo de tormenta

Figura 2.22: Gráficos matricial de velocidad del viento por tipo de tormenta

En ambos casos las interpretaciones son similares a las que se hicieron con el gráfico conjunto de densidad.

Podemos cambiar la configuración cambiando el número de columnas:

# Creamos el gráfico
ggplot(storm, aes(x = wind))  +
  geom_density(bw = 3) + 
  xlab("Wind speed (in knots)") +
  ylab("Density") +
  facet_wrap(~ type2, ncol = 2)
Gráficos matricial de velocidad del viento por tipo de tormenta

Figura 2.23: Gráficos matricial de velocidad del viento por tipo de tormenta

Aunque el gráfico se visualiza mejor también resulta más difícil la comparación entre todos los niveles.

Si deseamos cambiar la situación de las etiquetas del factor podemos utilizar la opción facet_grid.

# Creamos el gráfico
ggplot(storm, aes(x = wind))  +
  geom_density(bw = 3) + 
  xlab("Wind speed (in knots)") +
  ylab("Density") +
  facet_grid(type2 ~ .)
Gráficos matricial (grid) de velocidad del viento por tipo de tormenta

Figura 2.24: Gráficos matricial (grid) de velocidad del viento por tipo de tormenta

Esta opción nos resultará de mayor utilidad cuando tengamos que representar dos factores ya que se podrá situar en la filas uno de los factores y el otro en las columnas con la opción facet_grid(factor1 ~ factor2).

2.4.5 Dos variables numéricas

Los estadísticos han ideado varias formas diferentes de cuantificar la asociación entre dos variables numéricas en un banco de datos. Las medidas más comunes medidas buscan calcular algún tipo de coeficiente de asociación Los términos “asociación” y “correlación” están estrechamente relacionados; tanto que a menudo se usan indistintamente. La más habitual es la correlación lineal que cuantifica el grado de asociación lineal entre dos variables de tipo numérico. Para ejemplificar nuestros cálculos y gráficos utilizaremos las variables wind y preassure.

2.4.5.1 Resúmenes numéricos

La medida de correlación más utilizada es el coeficiente de correlación lineal de Pearson. El coeficiente de correlación de Pearson cuantifica el grado de asociación entre las variables en la escala -1 a 1, donde -1 indica una relación inversa (cuando una variable crece la otra decrece) y 1 indica una relación directa (cuando una crece la otra también lo hace. Valores próximo a cero indican que no hay asociación lineal entre las variables analizadas. Este coeficiente es la base para plantear lo que denominaremos más adelante los modelos de regresión lineal simple.

La definición formal del coeficiente de correlación de Pearson (\(\rho\)) viene dada por: \[\begin{equation} \rho = \frac{1}{n-1}\sum_{i=1}^n \frac{(x_i - \bar{x})(y_i - \bar{y})}{s_x s_y} \tag{2.7} \end{equation}\]

donde \(x_i\), \(y_i\) son las observaciones de la variable \(x\) e \(y\) respectivamente, \(\bar{x}\), \(\bar{y}\) son las medias muestrales de cada variable, y \(s_x\), \(s_y\) son las desviaciones típica de cada variable. El coeficiente trata de valorar la “covaraición” entre ambas variables, es decir, como afectan los cambios de valores en una variable en los valores de la otra, teniendo en cuenta la propia variabilidad de cada una de ellas.

Para obtener el coeficiente de correlación utilizamos la función cor().

cor(storm$wind,storm$pressure)
## [1] -0.9254911

El coeficiente de correlación resulta negativo, lo que indica que la velocidad del viento tiende a disminuir al aumentar la presión. Al estar próximo a -1 se puede intuir que dicha asociación es muy fuerte. Sin embargo, el coeficiente de correlación de Pearson debe interpretarse con cuidado debido a que está diseñado para medir una relación de tipo lineal, lo que implica que dicho coeficiente será engañoso cuando esta relación sea curva, o incluso peor, en forma de joroba.

¿Qué deberíamos hacer si pensamos que la relación entre dos variables no es lineal? No deberíamos usar el coeficiente de correlación de Pearson para medir la asociación en este caso. En cambio, podemos calcular lo que denominamos correlación de rango. La idea es muy simple. En lugar de trabajar con los valores reales de cada variable, los “clasificamos,” es decir, ordenamos cada variable de menor a mayor y asignamos las etiquetas “primero,” “segundo,” “tercero,” etc. a diferentes observaciones. Las medidas de correlación de rangos se basan en una comparación de los rangos resultantes. Los dos más populares son Spearman’s y Kendall’s. Ambos coeficientes se comportan de una manera muy similar al coeficiente de correlación de Pearson. Toman un valor de 0 si los rangos no están correlacionados, y un valor de +1 o -1 si están perfectamente relacionados.

Podemos calcular ambos coeficientes de correlación de rangos en R usando nuevamente la función cor. Esta vez necesitamos establecer el argumento del método en el valor apropiado: method = "kendall" o method = "spearman".

cor(storm$wind,storm$pressure,method = "kendall")
## [1] -0.7627645
cor(storm$wind,storm$pressure,method = "spearman")
## [1] -0.9025831

Los resultados obtenidos son compatibles con el del coeficiente de Pearson.

2.4.5.2 Visualización gráfica

Los coeficientes de correlación nos dan una forma simple de resumir las asociaciones entre variables numéricas. Sin embargo, son limitados, porque un solo número nunca puede resumir todos los aspectos de la relación entre dos variables. Es por eso que siempre visualizamos la relación entre dos variables. El gráfico estándar para mostrar asociaciones entre variables numéricas es un diagrama de dispersión, usando ejes horizontales y verticales para trazar dos variables como una serie de puntos. Para realizar este gráfico usamos la opción geom_point()

ggplot(storm, aes(x = wind, y = pressure)) + 
  geom_point() + 
  labs(x = "Wind speed (in knots)", y = "Air pressure (in mbar)")
Gráfico de dispersión de velocidad del viento vs presión atmosférica

Figura 2.25: Gráfico de dispersión de velocidad del viento vs presión atmosférica

En el gráfico se puede apreciar la relación de tipo lineal en orden o pendiente decreciente (cuando aumenta el viento disminuye la presión).

El problema de este gráfico es que no podemos apreciar todos los puntos, ya que si tenemos dos observaciones con los mismo valores en ambas variables, estos quedarían superpuestos. Para solucionar esta deficiencia podemos optar por otra versión del gráfico de dispersión que nos permita contabilizar el número de repeticiones cuando estas existan. Este gráfico se obtiene con la opción geom_hex(). Para poder realizarlo es necesario instalar la librería hexbin:

ggplot(storm, aes(x = wind, y = pressure)) + 
  geom_hex(bins = 25) + 
        labs(x = "Wind speed (in knots)", y = "Air pressure (in mbar)", fill = "n")
Gráfico de dispersión de velocidad del viento vs presión atmosférica (versión dos).

Figura 2.26: Gráfico de dispersión de velocidad del viento vs presión atmosférica (versión dos).

El parámetro bins segmenta el rango de cada variable en intervalos disjuntos. Lo que se representa es una gráfico de dispersión por intervalos, de forma que cada casilla representa todos los valores que quedan dentro del intervalo conjunto que obtenemos con ambas variables. Se observa que la tendencia se mantiene pero resulta posible ver que valores muestran una mayor o menor ocurrencia. La combinación de valores bajos de viento (< 40 mph) con altos de presión (> 990 mb) son los que más aparecen en el banco de datos.

Otra opción es agrupar una variable continua para que actúe como una variable categórica. Luego se puede usar un gráfico combinado de cajas para representar ambas variables Veamos un ejemplo:

ggplot(data = storm, aes(x = wind, y = pressure)) + 
  geom_boxplot(mapping = aes(group = cut_width(wind, 10))) + 
        labs(x = "Wind speed (in knots)", y = "Air pressure (in mbar)", fill = "n")
Gráfico de cajas discretizando la velocidad del viento vs presión atmosférica.

Figura 2.27: Gráfico de cajas discretizando la velocidad del viento vs presión atmosférica.

La interpretación es similar a la que se realizaba cuando trabajamos con una variable factor y otra numérica. Lo que resulta interesante es que podemos observar los intervalos con un mayor volumen de valores extremos o anómalos (valores de viento entre 30 y 90 mph).

2.5 Análisis Descriptivo avanzado

En esta unidad se amplían los procedimientos de análisis descriptivos vistos en el tema anterior para estudiar una o dos variables de tipo numérico o categórico al caso de más de dos variables de este tipo. No se hace un barrido a cualquier situación que pueda aparecer sino que se pretende mostrar los casos más habituales. Dichos casos son:

  • Tres variables categóricas.
  • Dos variables categóricas y una variable numérica.
  • Una variable categórica y dos variables numéricas.
  • Dos variables categóricas y dos variables numéricas.
  • Tres variables categóricas y dos variables numéricas.

De nuevo utilizaremos el conjunto de datos storms de la librería nasaweather.

2.5.1 Tres factores

Los procedimientos numéricos se restringen en este caso a la obtención de la tabla de frecuencias conjunta de las tres variables, mientras que los gráficos se basan en gráficos matriciales donde se consideran gráficos de barras.

A modo de ejemplo vamos a realizar el análisis conjunto de las variables year_f, month_f y type. Para poder realizar estos análisis utilizamos la función mytable de la librería moonBook. Para conocer todas las caracter´siticas de esta función se recomienda ver la ayuda help(mytable). EL problema principal con esta función es que si el número de nivles de los factores es demasiado grande resulta muy complicado visualizar todos los resultados en una única página. De hecho solo se pueden visulaizar resulatdos si el número de niveles del factor es 5 como máximo. Para poder ver los resultados en esta situación procedemos reando un conjunto de datos para cada tipo de tormenta. En este caso seleccionamos los meses centrales y los últimos cinco años para poder visualizar los resultados.

#{r aed045,error=FALSE,warning=FALSE,message=FALSE} #stormTD <- dplyr::filter(storm , month %in% c(7,8,9,10,11), # year %in% c(1996,1997,1998,1999,2000)) #mytable(year_f + type ~ month_f, data = stormTD) #

Para realizar le gráfico combinado de las tres variables categóricas utilizamos un gráfico matricial con dos factores y representamos dentro de cada combinación el gráfico de barras de la otra variable.

ords <- c("Tropical Depression", "Extratropical", "Tropical Storm", "Hurricane")
ggplot(storm, aes(x = type))  +
  geom_bar() + 
  scale_x_discrete(limits = ords) +
  xlab("Storm category") +
  ylab("Frequency") +
  facet_grid(year_f ~ month_f)+
  theme(axis.text.x = element_text(angle = 90)) 
Gráfico de barras para tipo de tormenta para los diferentes meses y años.

Figura 2.28: Gráfico de barras para tipo de tormenta para los diferentes meses y años.

¿Qué conclusiones podemos extraer de estos resultados? El gráfico resulta revelador, ya que se aprecian de forma directa las combinaciones de año - mes en al que no hay datos, y en aquellas donde si los hay se puede ver claramente cual es el tipo de tormenta más predominante.

Dado que la mayoría de los datos se producen entre los meses de agosto y octubre vamos a filtrar los datos para estudiar esas combinaciones únicamente.

storm_meses <- storm %>%
  filter(month_f == c("August","September","October"))
ords <- c("Tropical Depression", "Extratropical", "Tropical Storm", "Hurricane")
ggplot(storm_meses, aes(x = type))  +
  geom_bar() + 
  scale_x_discrete(limits = ords) +
  xlab("Storm category") +
  ylab("Frequency") +
  facet_grid(year_f ~ month_f) +
  theme(axis.text.x = element_text(angle = 90)) 
Gráfico de barras para tipo de tormenta para los diferentes meses y años (versión 2).

Figura 2.29: Gráfico de barras para tipo de tormenta para los diferentes meses y años (versión 2).

Este gráfico nos permite estudiar con más detalle los meses que concentran un mayor número de tormentas.

2.5.2 Dos factores, Una numérica

En este caso generalizamos el cálculo de medidas de localización y dispersión a esta situación, y analizamos los diferentes gráficos que podemos realizar en esta situación. Utilizamos las variables year_f, type, y wind. Mostraremos solo los datos para los años 1999 y 2000.

stormTD <- dplyr::filter(storm , year %in% c(1999,2000))
mytable(year_f + type ~ wind, data = stormTD)
## 
##                                          Descriptive Statistics stratified by 'year_f' and 'type'                                         
## ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 
##                                       1999                                                                2000                                
##       —————————————————————————————————————————————————————————————————— —————————————————————————————————————————————————————————————————— 
##       Extratropical  Hurricane  Tropical Depression Tropical Storm   p   Extratropical  Hurricane  Tropical Depression Tropical Storm   p  
##          (N=22)       (N=164)         (N=75)           (N=150)             (N=63)       (N=130)         (N=76)           (N=138)         
## ——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————— 
##  Wind  38.9 ± 20.3  90.5 ± 20.7     27.1 ±  3.9      47.7 ±  8.1   0.000  39.7 ± 13.2  79.5 ± 14.7     27.8 ±  2.6      46.2 ±  8.5   0.000
## ———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

Como antes el análisis de estas tablas es más complejo que tratar de representar los datos de forma que se puedan extraer conclusiones de forma más efectiva. Empezamos con el gráfico matricial mezclado con los gráficos de densidad.

# Creamos un nuevo factor ordenado de acurdo a la variable que estamos midiendo
storm$type2 <- reorder(storm$type, storm$wind)
# Creamos el gráfico
ggplot(storm, aes(x = wind, color = type2))  +
  geom_density(bw = 3) + 
  xlab("Wind speed (in knots)") +
  ylab("Density") +
  facet_grid(year_f ~ .)
Gráfico de densidad de la velocidad del viento para cada tipo de tormenta y año.

Figura 2.30: Gráfico de densidad de la velocidad del viento para cada tipo de tormenta y año.

Ahora realizamos el gráfico de cajas con una estructura similar

# Creamos el gráfico
ggplot(storm, aes(x = type2, y = wind))  +
  geom_boxplot() + 
  xlab("Storm category") +
  ylab("Wind speed (in knots)") +
  facet_grid(. ~ year_f) +
  theme(axis.text.x = element_text(angle = 90))
Gráfico de cajas de la velocidad del viento para cada tipo de tormenta y año.

Figura 2.31: Gráfico de cajas de la velocidad del viento para cada tipo de tormenta y año.

¿Qué conclusiones podemos extraer de este gráfico?

Otra versión de este gráfico podría ser:

# Creamos el gráfico
ggplot(storm, aes(x = year_f, y = wind, color = type2))  +
  geom_boxplot() + 
  xlab("Year") +
  ylab("Wind speed (in knots)") 
Gráfico de cajas de la velocidad del viento para cada tipo de tormenta y año (versión 2).

Figura 2.32: Gráfico de cajas de la velocidad del viento para cada tipo de tormenta y año (versión 2).

2.5.3 Un factor, Dos numéricas

En este caso generalizamos el análisis de correlación y el gráfico de dispersión con la inclusión del factor. Consideramos las variables type, wind y pressure. En primer lugar realizamos el estudio descriptivo numérico.

storm %>% 
  group_by(type) %>% # Segmentamos por tipo de tormenta
  summarise(cor = cor(wind,pressure)) # Obtenemos coeficientes de correlación
Tabla 2.6:
typecor
Extratropical-0.816
Hurricane-0.914
Tropical Depression-0.157
Tropical Storm-0.819

El resultado muestra gran asociación entre la velocidad del viento y la presión atmosférica en todas la categorías salvo para las Depresiones tropicales.

Veamos ahora el gráfico de dispersión conjunto. En primer lugar realizamos un único gráfico marcando con colores los tipos de tormenta

ggplot(storm, aes(x = wind, y = pressure, color = type )) + 
  geom_point() + 
  labs(x = "Wind speed (in knots)", y = "Air pressure (in mbar)")
Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta.

Figura 2.33: Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta.

Podemos ver como cada punto viene identificado según el tipo de tormenta. Los huracanes en la parte inferior donde se dan las relaciones entre velocidades del viento más altas y presiones atmosféricas más bajas. ¿Qué más podemos decir?

Podemos distinguir cada grupo introduciendo un gráfico matricial

# Creamos el gráfico
ggplot(storm, aes(x = wind, y = pressure))  +
  geom_point() + 
  xlab("Wind speed (in knots)") +
  ylab("Air pressure (in mbar)") +
  facet_grid(. ~ type2) 
Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta.

Figura 2.34: Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta.

En este gráfico se aprecia mejor el comportamiento de ambas variables en cada uno de los niveles del factor. Salvo en las depresiones tropicales donde no se aprecia asociación, en el resto de niveles se aprecia un relación de orden inverso. Lo que si podemos ver es que hay observaciones en algunas categorías que podrían corresponder a otras. En la categoría de tormentas tropicales tenemos combinaciones de velocidad y presión que parecen corresponder más a un huracán que a una tormenta tropical. Esto puede ser debido al protocolo de clasificación establecido o a la propia evolución de las tormentas.

2.5.4 Dos factores, Dos numéricas

Este caso es una generalización directa del caso anterior, ya que únicamente debemos añadir una nueva variable categórica. Consideramos las variables type, year_f, wind y pressure. Comenzamos con el análisis numérico:

tabla_cor <- storm %>% 
  group_by(year_f,type) %>% 
  summarise(cor = cor(wind,pressure))
# Visulaizamos la tabla de resultados de forma óptima
tabla_resumen <- dplyr::select(tabla_cor,year_f,type,cor)
# Arreglamos la tabla para una mejor visualización
spread(tabla_resumen, key = type, value = cor)
## # A tibble: 6 × 5
## # Groups:   year_f [6]
##   year_f Extratropical Hurricane `Tropical Depression` `Tropical Storm`
##   <fct>          <dbl>     <dbl>                 <dbl>            <dbl>
## 1 1995          -0.848    -0.885                 0.113           -0.731
## 2 1996          -0.826    -0.941                -0.290           -0.917
## 3 1997          -0.781    -0.973                -0.455           -0.748
## 4 1998          -0.726    -0.947                -0.271           -0.613
## 5 1999          -0.961    -0.916                -0.170           -0.661
## 6 2000          -0.915    -0.940                -0.127           -0.791

En esta tabla aparecen representados los coeficientes de correlación entre viento y presión para las diferentes combinaciones de niveles de las variables tipo y año. Se aprecian valores muy bajos en todas las combinaciones de la depresión tropical, mientras que en el resto hay asociaciones que pueden resultar interesantes de estudiar posteriormente. En el caso de los huracanes esas asociaciones son muy fuertes ya que muestran valores muy próximos a -1.

En cuanto a los procedimientos gráficos optamos por una combinación de los gráficos que utilizamos en la sección anterior. Representamos el gráfico de dispersión coloreando por tipo de tormenta, y usamos un diagrama matricial por año.

# Creamos el gráfico
ggplot(storm, aes(x = wind, y = pressure, color = type2))  +
  geom_point() + 
  xlab("Wind speed (in knots)") +
  ylab("Air pressure (in mbar)") +
  facet_grid(. ~ year_f) 
Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta y año.

Figura 2.35: Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta y año.

En todos los años se observa un comportamiento similar del resto de variables, indicando que el año no es una factor que pueda ser considerado como relevante. Si utilizamos la variable mes en su lugar el gráfico resultante es:

# Creamos el gráfico
ggplot(storm, aes(x = wind, y = pressure, color = type2))  +
  geom_point() + 
  xlab("Wind speed (in knots)") +
  ylab("Air pressure (in mbar)") +
  facet_grid(. ~ month_f) +
  theme(axis.text.x = element_text(angle = 90))
Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta y mes

Figura 2.36: Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta y mes

En este caso el comportamiento de los meses no es tan parecido. Si bien es cierto que en todas las combinaciones se aprecia una tendencia negativa (sube viento - baja presión), también se puede ver que los huracanes aparecen mayoritariamente en los meses de agosto a octubre. ¿Qué otra información podemos extraer de este gráfico?

2.5.5 Tres factores, Dos numéricas

Es una generalización directa de los dos casos anteriores. Se presenta únicamente el código para obtener los resultados. Añadimos la variable month_f a las del caso anterior.

tabla_cor <- storm %>% 
  group_by(year_f,month_f,type) %>% 
  summarise(cor = cor(wind,pressure))
# Visulaizamos la tabla de resultados de forma óptima
tabla_resumen <- dplyr::select(tabla_cor,year_f,month_f,type,cor)
spread(tabla_resumen, key = type, value = cor)
## # A tibble: 30 × 6
## # Groups:   year_f, month_f [30]
##    year_f month_f   Extratropical Hurricane `Tropical Depress…` `Tropical Storm`
##    <fct>  <fct>             <dbl>     <dbl>               <dbl>            <dbl>
##  1 1995   June             -0.688    NA                 NA                -0.849
##  2 1995   July             -0.816    NA                  0.121            -0.701
##  3 1995   August           -0.926    -0.750              0.294            -0.805
##  4 1995   September        -0.881    -0.931             -0.203            -0.937
##  5 1995   October          -0.954    -0.918             -0.0585           -0.727
##  6 1995   November         -0.968    NA                 NA                 1    
##  7 1996   June             -0.591    NA                 -0.828             0    
##  8 1996   July             -0.165    -0.779             -0.612            -0.955
##  9 1996   August           NA        -0.976             -0.0301           -0.830
## 10 1996   September        -0.887    -0.852              0.0622           -0.927
## # … with 20 more rows

¿Qué podemos decir de los resultados obtenidos?

Veamos ahora el gráfico matricial. Seleccionamos los meses de agosto a octubre para poder visualizarlo mejor.

storm_meses <- storm %>%
  filter(month_f == c("August","September","October"))
# Creamos un nuevo factor ordenado de acurdo a la variable que estamos midiendo
storm_meses$type2 <- reorder(storm_meses$type, storm_meses$wind)
# Creamos el gráfico
ggplot(storm_meses, aes(x = wind, y = pressure, color = type2))  +
  geom_point() + 
  xlab("Wind speed (in knots)") +
  ylab("Air pressure (in mbar)") +
  facet_grid(year_f ~ month_f) +
  theme(axis.text.x = element_text(angle = 90))
Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta, año y mes.

Figura 2.37: Gráfico de dispersion de presión vs velocidad para cada tipo de tormenta, año y mes.

¿Qué podemos decir de este gráfico?

2.6 Librería de interés

La libreria ggplotgui a través de la función ggplot_shiny nos permite generar una aplicación con la que se puede obtener el código correspondiente a un gráfico. Para utilizar dicha función basta con escribir ggplot_shiny(dataframe).

References

Wickham, Hadley, and Garrett Grolemund. 2016. R for Data Science. http://r4ds.had.co.nz/ ed. O’Reilly.