Diplomado: MANEJO DE ECOSISTEMAS MARINOS COSTEROS DEL CARIBE
Programa: Biología — Universidad de La Guajira
Facultad: Ciencias Básicas y Aplicadas


1 Introducción

En la Parte 1 aprendimos los fundamentos de R y RStudio. En esta segunda parte nos enfocamos en habilidades esenciales para el trabajo con datos reales:

  • Instalar y cargar paquetes
  • Importar datos desde archivos externos (CSV, Excel)
  • Manipular datos con dplyr (parte del ecosistema tidyverse)
  • Visualizar datos con ggplot2 usando ejemplos de ecosistemas marinos costeros del Caribe

2 Paquetes en R

2.1 ¿Qué es un paquete?

Un paquete (package) es una colección de funciones, datos y documentación que extiende las capacidades de R. Puedes imaginarlos como aplicaciones que instalas para agregar nuevas herramientas.

2.2 Instalar y cargar paquetes

Los Paquetes solamente se instalan una vez en los pc,

# Instalar paquetes (solo se hace UNA vez)
install.packages("tidyverse")   # Incluye dplyr, ggplot2, readr, tidyr, etc.
install.packages("readxl")      # Para leer archivos de Excel
install.packages("janitor")     # Para limpiar nombres de columnas

Cada vez que necesite usar el paquete debe llamarlo de la siguiente manera:

# Cargar paquetes (se hace al inicio de CADA sesión)
library(tidyverse)
library(readxl)
library(janitor)

💡 Regla de oro: install.packages() solo una vez; library() cada vez que abras RStudio.


3 Importación de Datos

3.1 Crear datos de ejemplo en R

¿Qué es un data.frame en R? Un data.frame es la estructura de datos más usada en R para almacenar datos tabulares, es decir, en formato de filas y columnas, similar a una hoja de cálculo de Excel o una tabla de base de datos.

Características principales:

  • Cada columna es un vector que puede ser de distinto tipo (numérico, texto, lógico, factor, etc.)
  • Todas las columnas tienen la misma longitud (igual número de filas)
  • Cada fila representa una observación o registro
  • Cada columna representa una variable

Antes de importar archivos externos, practiquemos creando un data.frame directamente en R. Usaremos datos simulados de monitoreo de arrecifes de coral en el Caribe colombiano:

set.seed(42)

arrecife <- data.frame(
  sitio        = rep(c("Isla Aguja", "Punta Gallinas", "Cabo de la Vela",
                       "Isla Salamanca", "Santa Marta"), each = 6),
  año          = rep(2019:2024, times = 5),
  cobertura_coral = c(
    rnorm(6, mean = 38, sd = 4),   # Isla Aguja
    rnorm(6, mean = 28, sd = 5),   # Punta Gallinas
    rnorm(6, mean = 32, sd = 3),   # Cabo de la Vela
    rnorm(6, mean = 45, sd = 6),   # Isla Salamanca
    rnorm(6, mean = 36, sd = 4)    # Santa Marta
  ),
  temperatura_C   = rnorm(30, mean = 28.5, sd = 1.2),
  salinidad_ppt   = rnorm(30, mean = 36.2, sd = 0.8),
  profundidad_m   = sample(3:18, 30, replace = TRUE)
)

# Vista preliminar
head(arrecife, 10)

3.2 Guardar y leer un archivo CSV

# Guardar el data.frame como CSV
write.csv(arrecife, "arrecife_caribe.csv", row.names = FALSE)

# Leer el CSV guardado
datos <- read.csv("arrecife_caribe.csv")

# Verificar la estructura
str(datos)
## 'data.frame':    30 obs. of  6 variables:
##  $ sitio          : chr  "Isla Aguja" "Isla Aguja" "Isla Aguja" "Isla Aguja" ...
##  $ año            : int  2019 2020 2021 2022 2023 2024 2019 2020 2021 2022 ...
##  $ cobertura_coral: num  43.5 35.7 39.5 40.5 39.6 ...
##  $ temperatura_C  : num  29 29.3 29.7 27.8 29.1 ...
##  $ salinidad_ppt  : num  35.9 36.3 36.7 37.3 35.6 ...
##  $ profundidad_m  : int  8 8 8 17 8 6 14 17 4 12 ...

3.3 Leer un archivo Excel (ejemplo)

# Sintaxis para leer un archivo .xlsx
datos_excel <- read_excel("mi_archivo.xlsx",
                          sheet  = 1,       # número o nombre de la hoja
                          skip   = 0)       # filas a omitir al inicio

# Limpiar nombres de columnas automáticamente
datos_excel <- datos_excel |> clean_names()

📁 Asegúrate de que el archivo .xlsx esté en la carpeta de tu proyecto de RStudio (directorio de trabajo).


4 Manipulación de Datos con dplyr

dplyr proporciona un conjunto de verbos intuitivos para transformar datos. Los más importantes son:

Función Acción
filter() Filtra filas según condiciones
select() Selecciona columnas
mutate() Crea o modifica columnas
summarise() Resume datos (medias, conteos, etc.)
group_by() Agrupa para operaciones por grupo
arrange() Ordena filas

El operador pipe |> encadena operaciones de izquierda a derecha, haciendo el código muy legible.

4.1 filter() — Filtrar filas

# Sitios con cobertura de coral mayor al 35%
alta_cobertura <- arrecife |>
  filter(cobertura_coral > 35)

nrow(alta_cobertura)
## [1] 15
head(alta_cobertura)

4.2 select() — Seleccionar columnas

# Solo nos interesan sitio, año y cobertura
resumen_simple <- arrecife |>
  select(sitio, año, cobertura_coral)

head(resumen_simple)

4.3 mutate() — Crear nuevas columnas

# Clasificar la cobertura como Alta, Media o Baja
arrecife <- arrecife |>
  mutate(
    categoria = case_when(
      cobertura_coral >= 40 ~ "Alta",
      cobertura_coral >= 30 ~ "Media",
      TRUE                  ~ "Baja"
    )
  )

table(arrecife$categoria)
## 
##  Alta  Baja Media 
##     7     5    18

4.4 group_by() + summarise() — Resúmenes por grupo

# Cobertura promedio y temperatura por sitio
resumen_sitio <- arrecife |>
  group_by(sitio) |>
  summarise(
    cobertura_media = round(mean(cobertura_coral), 2),
    cobertura_sd    = round(sd(cobertura_coral),   2),
    temp_media      = round(mean(temperatura_C),   2),
    n               = n()
  ) |>
  arrange(desc(cobertura_media))

resumen_sitio

4.5 arrange() — Ordenar datos

# Los 5 registros con mayor cobertura de coral
arrecife |>
  arrange(desc(cobertura_coral)) |>
  select(sitio, año, cobertura_coral, categoria) |>
  head(5)

5 Visualización con ggplot2

ggplot2 funciona mediante capas (layers). La lógica básica es:

ggplot(datos, aes(x = ..., y = ..., color = ...)) +
  geom_TIPO() +
  labs() +
  theme_ESTILO()

5.1 Gráfico de dispersión — Temperatura vs. Cobertura de coral

ggplot(arrecife, aes(x = temperatura_C, y = cobertura_coral, color = sitio)) +
  geom_point(size = 3, alpha = 0.75) +
  geom_smooth(method = "lm", se = FALSE, linewidth = 0.7, linetype = "dashed") +
  labs(
    title   = "Temperatura vs. Cobertura de Coral",
    subtitle = "Arrecifes del Caribe colombiano (2019–2024)",
    x       = "Temperatura superficial (°C)",
    y       = "Cobertura de coral (%)",
    color   = "Sitio"
  ) +
  theme_minimal(base_size = 13) +
  theme(legend.position = "bottom")
Relación entre temperatura superficial y cobertura de coral por sitio.

Relación entre temperatura superficial y cobertura de coral por sitio.

5.2 Boxplot — Cobertura de coral por sitio

ggplot(arrecife, aes(x = reorder(sitio, cobertura_coral, median),
                     y = cobertura_coral,
                     fill = sitio)) +
  geom_boxplot(alpha = 0.7, outlier.colour = "red", outlier.shape = 8) +
  geom_jitter(width = 0.15, alpha = 0.4, size = 1.5) +
  coord_flip() +
  labs(
    title = "Cobertura de Coral por Sitio",
    x     = NULL,
    y     = "Cobertura de coral (%)"
  ) +
  theme_classic(base_size = 13) +
  theme(legend.position = "none")
Distribución de la cobertura de coral por sitio de monitoreo.

Distribución de la cobertura de coral por sitio de monitoreo.

5.3 Gráfico de líneas — Tendencia temporal por sitio

arrecife |>
  group_by(sitio, año) |>
  summarise(media = mean(cobertura_coral), .groups = "drop") |>
  ggplot(aes(x = año, y = media, color = sitio, group = sitio)) +
  geom_line(linewidth = 1.1) +
  geom_point(size = 3) +
  scale_x_continuous(breaks = 2019:2024) +
  labs(
    title   = "Tendencia Temporal de Cobertura de Coral",
    subtitle = "Arrecifes del Caribe colombiano",
    x       = "Año",
    y       = "Cobertura promedio (%)",
    color   = "Sitio"
  ) +
  theme_minimal(base_size = 13) +
  theme(legend.position = "right")
Tendencia temporal de la cobertura de coral por sitio (2019–2024).

Tendencia temporal de la cobertura de coral por sitio (2019–2024).

5.4 Histograma — Distribución de salinidad

ggplot(arrecife, aes(x = salinidad_ppt, fill = categoria)) +
  geom_histogram(bins = 12, color = "white", alpha = 0.8) +
  facet_wrap(~ categoria, ncol = 1) +
  labs(
    title = "Distribución de Salinidad según Categoría de Cobertura de Coral",
    x     = "Salinidad (ppt)",
    y     = "Frecuencia",
    fill  = "Categoría"
  ) +
  theme_bw(base_size = 13) +
  theme(legend.position = "none")
Distribución de la salinidad registrada en todos los sitios.

Distribución de la salinidad registrada en todos los sitios.

5.5 Gráfico de barras con ggplot2

resumen_sitio |>
  ggplot(aes(x = reorder(sitio, cobertura_media),
             y = cobertura_media,
             fill = sitio)) +
  geom_col(alpha = 0.85) +
  geom_errorbar(aes(ymin = cobertura_media - cobertura_sd,
                    ymax = cobertura_media + cobertura_sd),
                width = 0.3, linewidth = 0.8) +
  coord_flip() +
  labs(
    title = "Cobertura Promedio de Coral por Sitio (± DE)",
    x     = NULL,
    y     = "Cobertura de coral (%)"
  ) +
  theme_classic(base_size = 13) +
  theme(legend.position = "none")
Cobertura promedio de coral por sitio con error estándar.

Cobertura promedio de coral por sitio con error estándar.


6 Exportar Resultados

6.1 Guardar una tabla como CSV

write.csv(resumen_sitio, "resumen_cobertura_coral.csv", row.names = FALSE)

6.2 Guardar un gráfico

# Guardar el último gráfico generado
ggsave("cobertura_por_sitio.png",
       width  = 8,
       height = 5,
       dpi    = 300)

# También puedes guardar un objeto gráfico específico
mi_grafico <- ggplot(arrecife, aes(x = temperatura_C, y = cobertura_coral)) +
  geom_point()

ggsave("temperatura_vs_coral.png", plot = mi_grafico, dpi = 300)

7 Próximos Contenidos

Esta es la Parte 2 de la guía. En las siguientes partes exploraremos:

  • Análisis estadísticos inferenciales (pruebas t, ANOVA, correlación)

Cristian Granados-Martínez PhD. — Programa de Biología, Universidad de La Guajira
2026