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.
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.
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.
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()).
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 |
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.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.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().
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.
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()
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()
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'
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.
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.