Introducción

En esta sesión de programación en R, haremos una introducción básica a la graficación y visualización de datos usando la librería ggplot, un paquete fundamental en R que implementa la “Gramática de los Gráficos” -un enfoque sistemático para construir visualizaciones mediante capas superpestas-. Esta gramática descompone un gráfica en componentes lógicos: datos (la información a representar), estéticas (mapeo de variables a elementos visuales como ejes, colores o formas), geometrías (tipos de gráficos como puntos, barras o líneas), escalas (ajuste de colores, ejes y leyendas), facetas (subgráficos para comparar grupos) y temas (persionalización del estilo). Utilizaremos la base de datos actividad saludable para mostrar como se construyen las gráficas paso a paso, enfocandonós en la sitenxis de ggplot2 y no en el análisis estadístico subyacente. El objetivo es dominar los comandos esenciales apra crear visualizaciones claras y personalizables, desde gráficos básicos (dispersión, barras, histogramas) hasta otros más avanzados (con facetas o múltiples capas).

En primer lugar, carguemos entonces la librería ggplot2 y la base de datos:

library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
library(readr)
datos = read_csv("actividad_vidasaludable.csv")
## Rows: 65528 Columns: 10
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (9): Tipo dcto, Sexo, Regimen, Actividad, Grupo Poblacional, Area, Comun...
## dbl (1): Edad
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

Estructura básica de ggplot2

ggplot2 se basa en lo que se conoce como la “Gramática de los Gráficos”, un concepto desarrollado por Leland Wilkinson que propone que cualquier gráfico estadístico puede construirse a partir de componentes fundamentales interconectados. Esta gramática proporciona un marco sistemático para la construcción de visualizaciones de datos, similar a cómo la gramática lingüística nos permite construir oraciones coherentes a partir de palabras y reglas. La implementación de esta gramática en ggplot2 sigue una estructura lógica y consistente que consta de varios elementos clave que trabajan en conjunto para producir visualizaciones efectivas.

La función ggplot(): La base de todo gráfico

Todo gráfico en ggplot2 comienza con la función ggplot(), que establece el lienzo básico y define el conjunto de datos que se utilizará. Esta función crea un objeto gráfico vacío que posteriormente se enriquece con capas adicionales. Lo fundamental aquí es que ggplot2 opera bajo un paradigma declarativo: describimos qué queremos mostrar, no cómo dibujarlo. Dentro de ggplot(), el argumento más importante es el mapeo estético (aes), que define cómo las variables del dataset se traducen en propiedades visuales como posición, color, forma o tamaño.

Mapas estéticos (aes): La conexión entre datos y visualizacion

Los mapeos estéticos, definidos dentro de aes(), son el puente entre los datos numéricos/categóricos y sus representaciones visuales. Aquí es donde especificamos qué variable debe ir en el eje x, cuál en el eje y, qué colores representarán categorías, o qué tamaños corresponderán a valores numéricos. Es crucial entender que los mapeos estéticos establecen relaciones entre variables y atributos visuales, pero no definen los valores específicos de esos atributos (eso se hace con parámetros fuera de aes()).

Geometría (geoms): Las formas visuales de los datos

Las funciones que comienzan con geom_ (como geom_point(), geom_bar(), geom_line(), etc.) son las que realmente dibujan algo en el gráfico. Cada geometría corresponde a un tipo específico de representación visual y tiene sus propios requerimientos de mapeos estéticos. Por ejemplo, geom_boxplot() necesita una variable x categórica y una y numérica, mientras que geom_histogram() solo requiere una variable numérica. Estas geometrías se añaden al gráfico base usando el operador +, demostrando el enfoque por capas de ggplot2. Algunos de estos son:

kable(tabla,allign="c") %>%
  kable_classic(full_width = F)
Función Tipo.de.gráfico Ejemplo.de.uso
geom_point() Gráfico de dispersión Relación entre edad y presión arterial
geom_line() Líneas Tendencias temporales
geom_bar() Barras Conteo de pacientes por hospital
geom_histogram() Histograma Distribución de glucosa en sangre
geom_boxplot() Diagrama de cajas Comparación de BMI por género
geom_smooth Línea de tendencia Regresión entre variables

Facetas: Creación de múltiples paneles

El sistema de facetas (con facet_wrap() o facet_grid()) permite dividir los datos en subconjuntos y mostrar cada subconjunto en un panel separado. Esto es particularmente útil para explorar cómo varían las relaciones entre variables a través de diferentes categorías. Las facetas mantienen escalas consistentes entre paneles (a menos que se especifique lo contrario), lo que facilita las comparaciones visuales.

  • facet_wrap(~variable):Varios paneles en una cruadrícula.
  • facet_grid(var1 ~ var2): Paneles cruzados dos variables.

Escalas: Control preciso de la representación visual

Las funciones scale_ permiten controlar cómo los valores de los datos se mapean a los atributos visuales. Hay escalas para colores (scale_color_ y scale_fill_), posiciones (scale_x_ y scale_y_), tamaños, formas y más. Estas funciones son esenciales para personalizar la apariencia del gráfico y asegurar que la visualización comunique efectivamente la información.

  • scale_x_continuos(): Ajusta el eje X continuo.
  • scale_color_manual(): Define colores manualmente.
  • scale_fill_gradient(): Colores degradados para rellenos.

Temas: El control estético del gráfico

El sistema de temas (theme()) controla todos los elementos no relacionados con los datos, como colores de fondo, fuentes de texto, ubicación de leyendas y más. ggplot2 incluye varios temas predefinidos (theme_bw(), theme_minimal(), etc.), pero también permite un control granular sobre cada elemento del gráfico mediante theme().

Etiquetas y anotaciones: Completando la comunicación visual

Las funciones labs() y annotate() permiten añadir títulos, subtítulos, etiquetas de ejes y anotaciones personalizadas. Estas son cruciales para hacer que el gráfico sea comprensible sin necesidad de explicación adicional, cumpliendo con el principio de que una buena visualización debe ser autoexplicativa.

Gráficos de Barras (Barplot)

Los gráficos de barras son ideales para representar frecuencias o cantidades de variables categóricas. En nuestro dataset de vida saludable, podemos usarlos para explorar la distribución de participantes por régimen de salud o comuna. Estas visualizaciones nos permiten comparar fácilmente categorías discretas, mostrando cómo se distribuyen las personas entre diferentes grupos. Por ejemplo, podemos visualizar cuántos participantes pertenecen al régimen contributivo versus subsidiado, o comparar la participación entre diferentes comunas.

datos %>%
  ggplot(aes(x = Regimen)) + 
  geom_bar() +
  labs(title = "Cantidad de participantes por régimen de salud",
       x = "Régimen",
       y = "Cantidad") +
  theme_minimal()

Este código utiliza el operador pipe (%>%) para tomar el dataframe datos y pasarlo como argumento principal a la función ggplot(), donde se define el mapeo estético con aes(x = Regimen) indicando que la variable “Regimen” se ubicará en el eje x. La función geom_bar() agrega la geometría de barras, la cual por defecto cuenta las frecuencias de cada categoría en la variable especificada (en este caso, mostrará cuántos participantes hay en cada tipo de régimen de salud). Las etiquetas (labs()) personalizan el título del gráfico y los nombres de los ejes x e y, mientras que theme_minimal() aplica un tema predefinido limpio y minimalista que mejora la legibilidad del gráfico eliminando elementos visuales innecesarios, resultando en una visualización clara que muestra la distribución de participantes según su régimen de salud. El gráfico luce mucho mejor, pero tal vez el color gris por defecto no resulta muy atractivo. Si lo deseamos, podemos cambiar el color con el que se representan tanto el área interior de las barras, como su borde, colocando explícitamente los valores dentro de la función geom_bar():

datos %>%
  ggplot(aes(x = Regimen)) + 
  geom_bar(fill="steelblue",color="gray2") +
  labs(title = "Cantidad de participantes por régimen de salud",
       x = "Régimen",
       y = "Cantidad") +
  coord_flip()+ #Para invertir la gráfica
  theme_minimal()

Como referencia para los nombres de los colores usados, revisar el siguiente link.

Ahora bien, si deseamos que cada grupo de datos (Regimen, en este caso) tenga colores distinto, basta con asignar, dentro de la “éstetica” (aes), el color como parámetro. En este caso al propio valor de “Regimen” pero convertido en tipo factor, es decir, a una variable categórica:

datos %>%
  ggplot(aes(x = Regimen,fill=as.factor(Regimen))) + 
  geom_bar() +
  labs(title = "Cantidad de participantes por régimen de salud",
       x = "Régimen",
       y = "Cantidad",
       fill="Regimen") +
  coord_flip()+ #Para invertir la gráfica
  theme_minimal()

Histograma (Histogram) y Gráfico de Densidad (Density Plot)

Los histogramas nos ayudan a entender la distribución de variables numéricas continuas, como la edad de los participantes. En el contexto de vida saludable, un histograma de edades revelaría si la participación está sesgada hacia ciertos grupos etarios. Podemos identificar si hay mayor participación de adultos jóvenes, mediana edad o adultos mayores, y detectar posibles patrones o brechas generacionales en el acceso a los programas de salud comunitaria. Similar a los histogramas pero con curvas suavizadas, los gráficos de densidad muestran la distribución de probabilidad de variables continuas. Para nuestros datos, podríamos superponer curvas de densidad por sexo para comparar cómo se distribuyen las edades entre hombres y mujeres que participan en los gimnasios comunitarios. Esta visualización es particularmente útil para identificar diferencias sutiles en las distribuciones que podrían pasar desapercibidas en un histograma.

Un primer histograma que podemos hacer a partir de este conjunto es ver el cómo están distribuidos los datos de la variable Edad:

datos%>%
  ggplot(aes(x=Edad))+
  geom_histogram(bindwidth=0.1,fill="#8B7D6B",bins=50)+
  labs(x="Edad",y="Frecuencia",title="Distibución de la variable Edad")+
  theme_bw()
## Warning in geom_histogram(bindwidth = 0.1, fill = "#8B7D6B", bins = 50):
## Ignoring unknown parameters: `bindwidth`

El código utiliza el operador pipe (%>%) para pasar el dataframe datos a la función ggplot(), donde se especifica que la variable “Edad” se ubicará en el eje x mediante aes(x=Edad). La función geom_histogram() genera el histograma con los siguientes parámetros: binwidth=0.1 establece el ancho de cada barra en 0.1 años (lo que permite una visión detallada de la distribución), fill="#8B7D6B"asigna un color beige/marrón claro a las barras usando un código hexadecimal, y bins=30 determina el número máximo de intervalos (aunque binwidth tiene prioridad). Las etiquetas se personalizan con labs() para los ejes x (“Edad”) e y (“Frecuencia”), además de agregar un título descriptivo. Finalmente, theme_bw() aplica un tema en blanco y negro (black and white) que proporciona un fondo limpio con líneas de cuadrícula discretas, mejorando la claridad de la visualización para analizar cómo se distribuyen las edades de los participantes en los programas de salud.

Ahora bien, dado que el dataset original contiene, por ejemplo, información categórica sexo, podemos aprovechar esta variable para representar, en distintos colores, cada una de estas categorías. Para ello, “mapeamos” la variable Sexo al argumento fill de la función:

datos%>%
  ggplot(aes(x=Edad,fill=Sexo))+
  geom_histogram(bins=50)+
  labs(x="Edad",y="Frecuencia",title="Distibución de la variable Edad")+
  theme_bw()

En este caso, si bien la gráfica no nos permite tener una visualización clara de la distribución de los valores, sí podemos conocer las proporciones entre los distintos ‘sexos’ presentes en los datos según la ‘Edad’.

Si, en su lugar, tenemos la necesidad de observar las distribuciones por separado para cada sexo, entonces podemos hacer uso de la función facet_grid() para separar los histogramas en filas (o columnas). Por ejemplo:

datos%>%
  ggplot(aes(x=Edad,fill=Sexo))+
  geom_histogram(bins=50)+
  facet_grid(~Sexo,scales = "free")+
  labs(x="Edad",y="Frecuencia",title="Distibución de la variable Edad")+
  theme_bw()

En este caso, el primer argumento de la función facet_grid() hace referencia a qué se va a representar en las filas y columnas. Así, la expresión Sexo~. puede leerse como: la variable ‘sexo’ en cada fila, el resto en las columnas. Por otro lado, el argumento scales = 'free' lo que produce es que cada histograma por separado se reescala de manera automática para lograr una mejor representación de los datos.

Del mismo modo, así como podemos usar la función geom_histogram() para representar el histograma, podemos emplear la función geom_density() para trazar un gráfico de densidad que asemeja una distribución continua:

datos%>%
  ggplot(aes(x=Edad))+
  geom_density(fill="#8B7D6B")+
  labs(x="Edad",y="Frecuencia",title="Distibución de la variable Edad")+
  theme_bw()

Gráficos de Dispersión (Scatterplot) y líneas de tendencia (geom_smooth)

Los scatterplots revelan relaciones entre dos variables numéricas. Aunque nuestro dataset tiene principalmente variables categóricas, podríamos explorar relaciones como edad versus frecuencia de asistencia (si tuviésemos ese dato). Estos gráficos son fundamentales para identificar correlaciones, tendencias o valores atípicos en los datos. Cada punto representa un individuo, permitiéndonos ver patrones generales y excepciones.

Para este caso, usaremos la base de datos predeterminada de R mtcars.

mtcars%>%
  ggplot(aes(x = wt, y = mpg)) +
    geom_point(size = 3, alpha = 0.7, color = "steelblue") +
    labs(title = "Eficiencia de Gasolina vs. Peso del Vehiculo",
         subtitle = "Datos mtcars",
         x = "Peso (1000 lbs)",
         y = "Millas por galos",
         caption = "Fuente: 1974 Motor Trend US magazine") +
    theme_minimal() 

Se crea un gráfico de dispersión (scatterplot) que muestra la relación entre el peso de los vehículos (wt en miles de libras) y su eficiencia de combustible (mpg en millas por galón) utilizando el conjunto de datos mtcars. La función ggplot() inicializa el gráfico especificando las variables para los ejes x e y, mientras que geom_point() añade los puntos con parámetros de personalización: tamaño (size = 3), transparencia (alpha = 0.7 para solapamiento visual) y color azul acero ("steelblue"). Las etiquetas (labs()) proporcionan contexto con un título principal, subtítulo, nombres descriptivos para los ejes y una nota de fuente. Finalmente, theme_minimal() aplica un diseño limpio y moderno al gráfico, eliminando elementos superfluos para destacar la relación inversa esperada entre peso y eficiencia de combustible, donde los vehículos más pesados tienden a mostrar un menor rendimiento de gasolina. Este gráfico resulta ideal para visualizar correlaciones y patrones en datos numéricos.

La función geom_smooth() en ggplot2 agrega una línea de tendencia (o curva) a un gráfico para visualizar patrones o relaciones entre variables. Por defecto, ajusta un modelo de suavizado (loess para menos de 1,000 observaciones o regresión lineal para más datos), permitiendo identificar tendencias generales incluso en puntos dispersos. Es útil para resaltar correlaciones, ya sea lineal (method = "lm") o no lineal, y puede incluir intervalos de confianza (se = TRUE) para mostrar la incertidumbre del modelo.

mtcars%>%
  ggplot(aes(x = wt, y = mpg)) +
    geom_point(size = 3, alpha = 0.7, color = "steelblue") +
    labs(title = "Eficiencia de Gasolina vs. Peso del Vehiculo",
         subtitle = "Datos mtcars",
         x = "Peso (1000 lbs)",
         y = "Millas por galos",
         caption = "Fuente: 1974 Motor Trend US magazine") +
    theme_minimal() +
    geom_smooth(method = "lm", color = "red")
## `geom_smooth()` using formula = 'y ~ x'

Gráfico de Cajas (Boxplot) y Gráficos de Violín (Violin plot)

Los boxplots resumen distribuciones numéricas por categorías, mostrando medianas, cuartiles y valores atípicos. En el contexto de vida saludable, podríamos usar boxplots para comparar la distribución de edades entre diferentes regímenes de salud o comunas. Estos gráficos son excelentes para identificar diferencias centrales y variabilidad entre grupos, mostrando de un vistazo dónde se concentran la mayoría de los participantes y si hay edades extremas que se apartan del patrón general. Combinando características de boxplots y gráficos de densidad, los violin plots muestran la distribución completa de los datos. Para nuestros datos de salud comunitaria, podríamos usarlos para visualizar cómo se distribuyen las edades por tipo de condición especial (desplazados, víctimas del conflicto, etc.). La forma ancha o estrecha del “violín” indica mayor o menor concentración de participantes en ciertos rangos de edad, proporcionando una visión más detallada que el boxplot tradicional.

Partiendo del mismo conjunto de datos de vida saludable, supongamos que queremos hacer una gráfica que muestre la distribución de edades según el régimen. Para ello, podríamos realizar una gráfica como la siguiente:

datos%>%
  ggplot(aes(x=Regimen,y=Edad,color=Regimen))+
  geom_point()+
  labs(x="Regimen",y="Edad",title="Edad según el régimen")+
  theme_classic()

En la gráfica mostrada, la distribución de las edades según el régimen se está graficando en el eje vertical, pero ya que se trata puntos representados en una sola dimensión, las formas de dichas distribuciones no resulta clara. Una opción para intentar visualizar mejor el significado de la gráfica es representar, con la función geom_jitter(), una dispersión horizontal y al azar de los datos:

datos%>%
  ggplot(aes(x=Regimen,y=Edad,color=Regimen))+
  geom_jitter(size=1,alpha=0.7)+
  labs(x="Regimen",y="Edad",title="Edad según el régimen")+
  theme_classic()

Sin embargo, esto todavía no nos permite visualizar con claridad la distribución de las edades según el régimen. Incorporemos entonces gráficos de caja:

datos%>%
  ggplot(aes(x=Regimen,y=Edad,color=Regimen))+
  geom_jitter(size=1,alpha=0.05)+
  geom_boxplot(alpha=0.7)+
  labs(x="Regimen",y="Edad",title="Edad según el régimen")+
  theme_classic()

Ahora que las cajas han sido dibujadas en el gráfico, podemos entender la forma de las distribuciones de puntuaciones para cada género ya que: para cada caja, la línea gruesa central representa la ‘mediana’ de los datos, la línea horizontal de la primera caja inferior representa el 1er cuartil, mientras que la línea horizontal de la caja superior representa el 3er cuartil. A las líneas verticales que se extienden de las cajas se les llama ‘bigotes’, y estas alcanzan los valores mínimos y máximos, mientras que los puntos que se encuentren fuera de estos rangos se les denomina ‘outliers’.

Como alternativa a los gráficos de caja, podemos emplear gráficos de violín para observar, del mismo modo, la distribución de los datos subyacentes:

datos%>%
  ggplot(aes(x=Regimen,y=Edad,color=Regimen))+
  geom_jitter(size=0.5,color="gray")+
  geom_violin(aes(fill=Regimen),alpha=0.8)+
  labs(x="Regimen",y="Edad",title="Edad según el régimen")+
  theme_classic()

En el gráfico de violín se representa, en el eje vertical, la distribución de los datos como si se tratara de un gráfico de densidad, y se traza la imagen especular en el eje a fin de obtener el resultado en forma de ‘violín’ como se observa en la gráfica. Si sobre este gráfico superponemos el boxplot:

datos%>%
  ggplot(aes(x=Regimen,y=Edad,color=Regimen))+
  geom_jitter(size=0.5,color="gray")+
  geom_violin(alpha=0.8)+
  geom_boxplot(color="black",alpha=0.7)+
  labs(x="Regimen",y="Edad",title="Edad según el régimen")+
  theme_classic()

Podemos entender mejor la relación entre la distribución de los datos y el gráfico de cajas asociados a estos.

Conclusiones

La librería ggplot2 se revela como una herramienta fundamental para el análisis de datos, ofreciendo capacidades gráficas avanzadas que permiten visualizar información de manera precisa y profesional. A través de sus diversas funciones, podemos representar eficientemente distribuciones, correlaciones, patrones y tendencias en nuestros conjuntos de datos, lo que resulta invaluable tanto para el análisis exploratorio como para el desarrollo de modelos predictivos. Los ejemplos presentados constituyen solo una muestra introductoria del vasto potencial de esta librería, que incluye muchas otras posibilidades de visualización.

Para quienes deseen profundizar en el uso de ggplot2, se recomienda consultar la documentación oficial de la librería, así como explorar recursos especializados como The R Graph Gallery y Data Visualization with ggplot2. Este último resulta particularmente valioso por presentar una amplia colección de visualizaciones profesionales, acompañadas de sus respectivos códigos fuente, que incluyen no solo ejemplos con ggplot2 sino también con otras librerías gráficas de R. Este tipo de recursos resultan ideales para ampliar el repertorio de técnicas de visualización y dominar el arte de comunicar insights a través de gráficos efectivos.