Se configura el entorno en R, definiendo el directorio de trabajo y cargando los paquetes necesarios para asegurar un flujo de trabajo ordenado y reproducible.
# ------------------------------------------------------------
# Instalación y carga de paquetes
# ------------------------------------------------------------
# Establecer mirror de CRAN
options(repos = c(CRAN = "https://cloud.r-project.org"))
# Lista de paquetes necesarios para el curso
packages <- c(
"openxlsx", # lectura/escritura de Excel
"terra", # manejo de datos raster
"zoo", # series de tiempo
"hydroTSM", # herramientas hidrológicas
"ggplot2", # gráficos
"ggnewscale", # múltiples escalas en gráficos
"ggspatial", # elementos espaciales en mapas
"colorspace", # manejo de colores
"tidyterra", # integración terra + tidyverse
"sf" # datos vectoriales espaciales
)
# ------------------------------------------------------------
# Instalación de paquetes (solo si no están instalados)
# ------------------------------------------------------------
for (pkg in packages) {
if (!requireNamespace(pkg, quietly = TRUE)) {
install.packages(pkg)
}
}
# ------------------------------------------------------------
# Carga de paquetes
# ------------------------------------------------------------
invisible(
lapply(packages, function(pkg) {
suppressPackageStartupMessages(
library(pkg, character.only = TRUE)
)
})
)## Warning: package 'ggplot2' was built under R version 4.5.2
Se importan datos desde diferentes formatos (.csv y .xlsx)y se integran en una sola base, organizando la información para su análisis.
# Leer archivo CSV con datos de precip
data_csv <- read.csv(
"./inputs/data_prec.csv",
stringsAsFactors = FALSE
)
# Visualizar las primeras filas
head(data_csv)## Time Prec
## 1 1/1/1981 53.45
## 2 1/2/1981 192.57
## 3 1/3/1981 386.57
## 4 1/4/1981 176.06
## 5 1/5/1981 83.82
## 6 1/6/1981 41.35
# leer datos en Excel con datos de caudal
data_xlsx <- read.xlsx('./inputs/data_runoff.xlsx',
sheet = 1, detectDates = TRUE)
# visualizar las primeras filas
head(data_xlsx)## Time Runoff
## 1 1981-01-01 10.7
## 2 1981-02-01 74.8
## 3 1981-03-01 213.1
## 4 1981-04-01 96.4
## 5 1981-05-01 4.7
## 6 1981-06-01 4.6
# extraer datos
time <- as.Date(data_csv$Time, format = '%d/%m/%Y')
prec <- data_csv$Prec
runoff <- data_xlsx$Runoff
# crear dataframe con datos combinados
database <- data.frame(Time = time, Prec = prec, Runoff = runoff)
# visualizar primeras y 煤ltimas filas
head(database)## Time Prec Runoff
## 1 1981-01-01 53.45 10.7
## 2 1981-02-01 192.57 74.8
## 3 1981-03-01 386.57 213.1
## 4 1981-04-01 176.06 96.4
## 5 1981-05-01 83.82 4.7
## 6 1981-06-01 41.35 4.6
## Time Prec Runoff
## 115 1990-07-01 26.55 0.4
## 116 1990-08-01 18.59 0.6
## 117 1990-09-01 14.38 0.8
## 118 1990-10-01 14.73 8.9
## 119 1990-11-01 13.36 29.7
## 120 1990-12-01 14.74 26.2
Se muestran distintas formas de guardar datos en R, permitiendo conservar resultados y reutilizarlos en futuros análisis.
# exportar datos en distintos formatos
# CSV: formato de texto simple, compatible con Excel y otros programas
write.csv(database, './outputs/database.csv', row.names = FALSE)
# TXT: archivo de texto con separador TAB, 煤til para intercambio de datos
write.table(database, './outputs/database.txt',
sep = "\t", row.names = FALSE)
# Excel: formato más amigable para usuarios no técnicos
write.xlsx(database, './outputs/database.xlsx',
rowNames = FALSE)
# RData: guarda uno o varios objetos de R (se carga con load())
save(database, file = './outputs/database.RData')
# RDS: guarda un solo objeto de R (se lee con readRDS())
saveRDS(database, './outputs/database.rds')# leer datos en formato RData
# carga uno o varios objetos directamente en el entorno de trabajo
load('./outputs/database.rdata')
# el objeto ya existe con su nombre original
head(database)## Time Prec Runoff
## 1 1981-01-01 53.45 10.7
## 2 1981-02-01 192.57 74.8
## 3 1981-03-01 386.57 213.1
## 4 1981-04-01 176.06 96.4
## 5 1981-05-01 83.82 4.7
## 6 1981-06-01 41.35 4.6
# leer datos en formato RDS
# se debe asignar a un objeto al momento de leerlo
ans <- readRDS('./outputs/database.rds')
# visualizar contenido
head(ans)## Time Prec Runoff
## 1 1981-01-01 53.45 10.7
## 2 1981-02-01 192.57 74.8
## 3 1981-03-01 386.57 213.1
## 4 1981-04-01 176.06 96.4
## 5 1981-05-01 83.82 4.7
## 6 1981-06-01 41.35 4.6
Se elaboran gráficos como hidrogramas, hietogramas y diagramas de dispersión para analizar el comportamiento temporal y la relación entre variables.
# crear hidrograma (caudal vs tiempo)
plot(x = time, y = runoff,
type = 'o', pch = 16, lwd = 1.8, col = 'darkblue',
xlab = 'Tiempo [meses]',
ylab = 'Escurrimiento [mm/mes]',
main = 'Hidrograma')# crear hietograma (precipitación vs tiempo)
barplot(height = prec, names.arg = time,
col = 'dodgerblue',
xlab = 'Tiempo [meses]',
ylab = 'Precipitación [mm]',
main = 'Hietograma')# crear diagrama de dispersión (precipitación vs escorrentía)
plot(x = prec, y = runoff,
cex = 1, pch = 21, col = 'black', bg = 'cyan',
xlab = 'Precipitación [mm/mes]',
ylab = 'Escorrimiento [mm/mes]',
main = 'Diagrama de dispersión')
# agregar línea de regresión lineal
abline(lm(runoff ~ prec), col = 'red', lty = 2, lwd = 2)# crear diagrama de cajas (distribución mensual)
bp <- t(matrix(runoff, nrow = 12)) # ordenar datos por año
boxplot(x = bp,
border = 'black',
boxwex = 0.6,
staplewex = 0.2,
col = 'gray90',
medcol = "red",
medlwd = 2,
boxlty = 3,
whisklty = 1,
staplelwd = 1,
pch = 20,
names = month.abb,
xlab = 'Mes',
ylab = 'Escorrimiento [mm/mes]',
main = 'Boxplot')Se utilizan herramientas para combinar múltiples gráficos en una sola figura y automatizar su generación, mejorando la presentación de resultados.
# png('./outputs/multipanel.png', units='px', height=500, width=700)
# ajustar parámetros gráficos
par(
mfrow = c(2, 2), # 4 gráficos (2x2)
mar = c(4, 4, 1.5, 0.5), # márgenes internos
oma = c(0, 0, 1, 1), # márgenes externos
mgp = c(1.8, 0.3, 0), # posición de textos en ejes
cex = 0.7, # tamaño general del texto
cex.axis = 0.7, # tamaño de ejes
tck = -0.02 # marcas hacia adentro
)
# crear figuras
plot(x = time, y = runoff, type = 'l', lwd = 1.8, col = 'blue',
xlab = 'Tiempo [meses]', ylab = 'Escorrentía [mm/mes]',
main = 'Hidrograma')
barplot(height = prec, names.arg = time, col = 'darkred', border = 'darkred',
xlab = 'Tiempo [meses]', ylab = 'Precipitación [mm]',
main = 'Hietograma')
plot(x = prec, y = runoff, cex = 1, pch = 21, col = 'black', bg = 'cyan',
xlab = 'Precipitación [mm/mes]', ylab = 'Escorrentía [mm/mes]',
main = 'Diagrama de dispersión')
abline(lm(runoff ~ prec), col = 'red', lty = 2)
boxplot(x = t(matrix(runoff, nrow = 12)), border = 'black', boxwex = 0.3,
staplewex = 0.2, col = 'gray90', medcol = "red", medlwd = 1,
boxlty = 1, whisklty = 1, staplelwd = 1, pch = 20,
names = month.abb, xlab = 'Mes', ylab = 'Escorrentía [mm/mes]',
main = 'Boxplot')Se cargan datos espaciales como el modelo de elevación, la cuenca y la red de ríos, fundamentales para el análisis hidrológico.
# leer datos geoespaciales de la cuenca
dem <- rast('./inputs/dem.tif')
cat <- vect('./inputs/basin.shp')
riv <- vect('./inputs/rivers.shp')
# explorar atributos de los datos vectoriales
as.data.frame(cat)## Region Area Vertiente Outlet COMID
## 1 A 5379.229 Pacific ETI 1
## class : SpatRaster
## size : 251, 429, 1 (nrow, ncol, nlyr)
## resolution : 0.004166667, 0.004166667 (x, y)
## extent : -80.89583, -79.10833, -4.383333, -3.3375 (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326)
## source : dem.tif
## name : dem
## [1] 0.004166667 0.004166667
## [1] "GEOGCRS[\"WGS 84\",\n ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n MEMBER[\"World Geodetic System 1984 (Transit)\"],\n MEMBER[\"World Geodetic System 1984 (G730)\"],\n MEMBER[\"World Geodetic System 1984 (G873)\"],\n MEMBER[\"World Geodetic System 1984 (G1150)\"],\n MEMBER[\"World Geodetic System 1984 (G1674)\"],\n MEMBER[\"World Geodetic System 1984 (G1762)\"],\n MEMBER[\"World Geodetic System 1984 (G2139)\"],\n MEMBER[\"World Geodetic System 1984 (G2296)\"],\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]],\n ENSEMBLEACCURACY[2.0]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"geodetic latitude (Lat)\",north,\n ORDER[1],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n AXIS[\"geodetic longitude (Lon)\",east,\n ORDER[2],\n ANGLEUNIT[\"degree\",0.0174532925199433]],\n USAGE[\n SCOPE[\"Horizontal component of 3D system.\"],\n AREA[\"World.\"],\n BBOX[-90,-180,90,180]],\n ID[\"EPSG\",4326]]"
# enmascarar modelo de elevacion respecto de la cuenca
dem_cat <- mask(dem, cat)
# mostrar objeto raster enmascarado
plot(dem_cat)Se construyen mapas que integran información espacial e hidrológica, facilitando la interpretación del territorio.
# Crear un mapa básico
plot(dem_cat,
col = terrain.colors(100, alpha=0.5),
main = 'Mapa de la cuenca',
xlab='Longitud',
ylab='Latitud')
plot(cat, lwd=1, add = TRUE)
plot(riv, lwd=3, col = 'dodgerblue2', add = TRUE)
grid()# crear mapa de relieve
slp <- terrain(dem_cat, "slope", unit = "radians")
asp <- terrain(dem_cat, "aspect", unit = "radians")
hsd <- shade(slp, asp, angle=45, direction=300, normalize=TRUE)
dem.df <- as.data.frame(dem_cat, xy=TRUE)
names(dem.df)[3] <- "alt"
hsd.df <- as.data.frame(hsd, xy=TRUE)
names(hsd.df)[3] <- "hillshade"
# crear mapa con relieve sombreado
plt <- ggplot() +
geom_raster(data = hsd.df, aes(x, y, fill = hillshade), show.legend = FALSE) +
scale_fill_distiller(palette = "Greys") +
new_scale_fill() +
geom_raster(data = dem.df, aes(x, y, fill = alt), alpha = 0.7) +
scale_fill_gradientn(colors = terrain.colors(10), name = "Elevación (msnm)") +
geom_sf(data = st_as_sf(cat), color = 'black', fill = NA) +
geom_sf(data = st_as_sf(riv), color = 'dodgerblue2', size = 0.3, linewidth = 1) +
theme_bw() +
labs(title = 'Cuenca de estudio', subtitle = 'Mapa de elevación',
x = 'Longitud', y = 'Latitud') +
annotation_scale(location = "br", width_hint = 0.3) +
annotation_north_arrow(location = "tl", which_north = "true",
pad_x = unit(0.2, "in"), pad_y = unit(0.2, "in"),
style = north_arrow_fancy_orienteering)
# mostrar figura
print(plt)# guardar figura en carpeta de salida
ggsave('./outputs/map_cuenca.png', plot=plt, units='px', height=1000, width=1500, scale=2)```