Los estadísticos son insuficientes para conocer una variable; la siguiente figura es muy conocida y presenta una serie de pares de datos $X$ e $Y$ con los mismos estadísticos que son completamente diferentes:

Disponer de los estadísticos es insuficiente para conocer cómo son los valores que toma una variable, cómo se distribuye. Se torna necesario describir mejor ese comportamiento mediante análisis gráficos. En capítulos anteriores se trabajó con las posibilidades que ofrece ggplot2 para visualizar datos. A continuación, se desarrollan esas posibilidades y se estudia cómo describen nuestros datos esos gráficos.
El primer paso es cargar los datos de trabajo, ya conocidos, y se da comienzo con el trabajo:
library(tidyverse)
train <- read_csv("./data/train.csv")
Descripción gráfica de factores
Si numéricamente tenemos frecuencias absolutas o frecuencias relativas, los gráficos más sencillos para describir estas variables son los gráficos de barras y gráficos de sectores.
resumen <- train %>%
group_by(Gender) %>%
summarise(clientes = n())
ggplot(resumen, aes(x = '', y = clientes, fill = Gender)) +
geom_bar(stat = "identity", width = 1) +
coord_polar("y", start = 0)

Con datos absolutos, el gráfico de sectores pierde sentido; aunque es posible conocer cómo se distribuye la variable en la población, es necesaria la «relativización», la obtención de porcentajes.
resumen <- train %>%
group_by(Gender) %>%
summarise(porc_clientes = n() / nrow(train))
ggplot(resumen, aes(x = '', y = porc_clientes, fill = Gender)) +
geom_bar(stat = "identity", width = 1) +
coord_polar("y", start = 0)

En el caso concreto de los gráficos de sectores, puede ser más sencillo emplear los gráficos propios del módulo base, el corazón de R. En ese caso, se dispone de la función pie():
resumen <- train %>%
group_by(Gender) %>%
summarise(porc_clientes = n() / nrow(train))
pie(resumen$porc_clientes,
labels = paste0(resumen$Gender, ': ', round(resumen$porc_clientes * 100, 1), '%'),
main = "Gráfico sectores por sexo")

El código y el gráfico (aparentemente) son más sencillos de entender. Este tipo de representación está limitada cuando el factor a analizar tiene un gran número de niveles, como sucede con la variable Region_Code.
resumen_reg <- train %>%
group_by(Region_Code) %>%
summarise(porc_clientes = n() / nrow(train))
pie(resumen_reg$porc_clientes,
labels = paste0(resumen_reg$Region_Code, ': ', round(resumen_reg$porc_clientes * 100, 1), '%'),
main = "Gráfico sectores por Región")

La variable Region_Code tiene muchos posibles valores. Una puntualización: aunque en los datos de partida tiene un formato numérico, estamos ante un factor; este ejemplo ilustra la importancia de conocer los datos que se están empleando. El conocimiento de las fuentes de información ha de ser previo al análisis descriptivo, o bien este análisis nos puede servir para identificar estas incoherencias. Recuperando la definición de los datos anteriormente planteada:
- Region_Code: Unique code for the region of the customer.
«Código único» no expresa un valor numérico, expresa una codificación. Puede parecer un caso sencillo, pero es importante tener en cuenta estas situaciones cuando se trabaja con un gran volumen de variables. Para factores como este, con un gran número de niveles, puede ser más apropiado el uso de gráficos de barras.
train %>%
group_by(Region_Code) %>%
summarise(porc_clientes = n() / nrow(train)) %>%
ggplot(aes(x = Region_Code, y = porc_clientes)) +
geom_bar(stat = "identity")

En este código no se genera el habitual data.frame intermedio: directamente podemos aplicar ggplot sobre la sumarización; es otro modo de trabajar si no se quiere disponer de la sumarización. Se observa que el eje x interpreta la variable Region_Code como numérica: establece rangos numéricos, no aparece cada valor. Se recomienda empezar a describirla como un factor. Esta es una situación habitual que se da en los datos importados: hay valores cualitativos que se almacenan en variables cuantitativas y viceversa. Se trata de un problema común que se encuentra el científico de datos.
train %>%
group_by(Region_Code = as.factor(Region_Code)) %>%
summarise(`Porcentaje de clientes` = round(n() * 100 / nrow(train), 2)) %>%
ggplot(aes(x = Region_Code, y = `Porcentaje de clientes`)) +
geom_bar(stat = "identity") +
ggtitle("Porcentaje de clientes por región")

En esta nueva propuesta el eje x es distinto: ya no hay intervalos, cada región tiene su correspondiente código. Si la variable es numérica, se disponen intervalos. En cualquier caso, se aprecia cómo se complica la lectura de esos datos porque el factor Region_Code tiene un gran número de niveles.
Es importante destacar la relevancia descriptiva de los gráficos de barras, ya que nos permiten conocer la composición de los datos en función de los niveles de un factor. Además, se está repitiendo el mismo código en cada uno de los gráficos propuestos. Cuando estamos en estas situaciones, es útil crear funciones:
# Función para describir factores
describe_factor <- function(df, fct) {
df %>%
group_by(factor_analisis = as.factor(.data[[fct]])) %>%
summarise(`Porcentaje de clientes` = n() / nrow(df)) %>%
ggplot(aes(x = factor_analisis, y = `Porcentaje de clientes`)) +
geom_bar(stat = "identity") +
ggtitle(paste0("Porcentaje de clientes por ", fct))
}
describe_factor(train, 'Gender')

El código que describe el factor es repetitivo; para simplificar la programación en R se emplea una función. No es el objeto de esta formación aprender a realizar funciones con R, pero se van a ilustrar algunos ejemplos de uso. Además, cuando se usa dplyr, trabajar con .data[[fct]] facilita el uso de funciones para referir valores de un objeto de R (en este caso, los nombres). En este caso, la función describe_factor crea una sumarización previa por el factor que describe el parámetro de la función fct y, posteriormente, se genera el gráfico de barras más sencillo posible con ggplot2: solo se parametriza el título del gráfico uniendo un texto con el nombre de la variable. Esta función puede describir también variables cuantitativas:
describe_factor(train, 'Age')

Se recuerda que una variable cuantitativa puede tener un número finito de elementos, lo que da pie a ser tratada como un factor; paradigma de esta situación es la variable edad en prácticamente todos los conjuntos de datos.
Descripción gráfica de variables numéricas
Vistos con anterioridad los estadísticos de posición, variación y forma para las variables cuantitativas, es imprescindible la descripción gráfica. En el capítulo introductorio a ggplot2 se pusieron sobre el papel diversos análisis gráficos que servirán para realizar esta descripción. Se parte con los gráficos más sencillos, realizados con el código más simple de ggplot2, y paulatinamente se irá sofisticando ese código a lo largo del curso.
Se comienza con los histogramas y los gráficos de densidad:
# Histogramas
ggplot(data = train, aes(x = Age)) +
geom_histogram(bins = 30)
# Gráficos de densidades
ggplot(data = train, aes(x = Age)) +
geom_density()
# Ambos
ggplot(data = train, aes(x = Age)) +
geom_histogram(aes(y = ..density..), binwidth = 5, fill = "grey", alpha = 0.5) +
geom_density(color = 'blue', size = 1)

Tanto histograma como gráfico de densidad representan todos los posibles valores que puede tomar la variable cuantitativa. Nunca se representará un valor que no aparece y nunca se dejará de representar algún valor existente. En el caso del gráfico de densidad, la línea continua deja una superficie por debajo de la curva de tamaño 1; es decir, el 100% de las observaciones están en algún punto por debajo de esa curva y, de izquierda a derecha, se puede ir acumulando el porcentaje de observaciones (se puede ir acumulando densidad).
Volviendo con los principales estadísticos descriptivos, se puede buscar cómo aparecen reflejados en el histograma:
ggplot(data = train, aes(x = Age)) +
geom_histogram(bins = 30) +
geom_vline(aes(xintercept = mean(Age)), color = "red", linetype = "dashed") +
geom_vline(aes(xintercept = median(Age)), color = "green")
La moda se sitúa en la barra más alta: es el valor que más se repite. La forma de la variable parece que tiene, a su vez, como dos formas distintas: la encuesta se ha realizado a clientes jóvenes y a clientes en el rango entre 40 y 50 años; como mucho se ha preguntado a clientes de 90 años y, en ningún caso, a clientes menores de edad. En este caso, los estadísticos descriptivos por sí solos poco podían aportar. En cuanto al código empleado, hay particularidades en el gráfico que une histograma y densidad: al ser dos valores en distinta escala, es necesario realizar un ajuste para que ambos gráficos se puedan ver en uno, y por eso se usan densidades en lugar de conteos.
Podemos representar algunas de esas medidas en el gráfico:
ggplot(data = train, aes(x = Age)) +
geom_density() +
geom_vline(aes(xintercept = mean(Age)), color = "red") +
geom_text(aes(x = mean(Age), y = 0.01, label = "Media"), color = "red", angle = 90, vjust = -1)

Con geom_vline añadimos una barra vertical y con geom_text añadimos texto a nuestro gráfico de ggplot2. En cuanto a la asimetría, un valor muy positivo indica asimetría a la derecha (cola larga a la derecha), algo muy evidente viendo cómo se distribuye la variable a lo largo del gráfico de densidad. La curtosis poco o nada puede aportar con una forma tan peculiar del gráfico de densidad donde parece que hay dos formas diferenciadas dentro de los datos.
A continuación, se analiza la variable Annual_Premium con un comportamiento sustancialmente distinto:
ggplot(data = train, aes(x = Annual_Premium)) +
geom_density(fill = "blue", alpha = 0.3)

Cuando se trabaja con variables como importes, se puede complicar el histograma y el gráfico de densidades; es recomendable jugar con el número de grupos, anchura de los mismos, etc. En este caso concreto se aprecia que la forma, la distribución de los valores de la variable, tiene un punto alto en el 0: un valor modal en el 0. No se deberían tener clientes sin prima si se trabaja con una base de clientes de un ramo de salud. Posteriormente, tiene una forma muy asimétrica hacia la derecha debido a que hay valores de prima muy altos. Esos valores 0 hacen que la media sea más baja que la mediana; la desviación típica es muy alta. Como se vio con anterioridad, estábamos ante valores muy altos de asimetría y de curtosis (apuntamiento). Este tipo de distribución es muy típica de importes: ninguno es menor que 0 y hay importes muy altos.
Además de los histogramas y los gráficos de densidad, en la descripción de las posibilidades gráficas se dio importancia a los boxplots; estos gráficos contienen mucha y muy valiosa información sobre cómo es una variable cuantitativa:
ggplot(train, aes(y = Age)) +
geom_boxplot() +
coord_flip()

Mediante coord_flip() se ha rotado la figura generada con ggplot2. Esta representación gráfica está muy ligada a los estadísticos de posición y a algunos estadísticos de dispersión:
ggplot(train, aes(y = Annual_Premium)) +
geom_boxplot() +
coord_flip()

Ya se vio con el gráfico de densidad que la prima anual toma unos valores más complejos. En este caso, la caja parece muy estrecha y aparecen una serie de puntos por la derecha que dificultan la descripción de los datos. Cuando aparecen esos puntos en estos gráficos, los posibles valores que toma la variable tienen algún valor atípico: la distribución de la variable tiene outliers. Es uno de los posibles problemas que pueden plantear los datos numéricos y que se desarrollarán en capítulos posteriores. Saludos.