1 Introducción y Metodología

El presente informe estadístico analiza la variable Precipitación registrada en la estación meteorológica del Antisana. Esta variable es fundamental para cuantificar la oferta hídrica y la recarga de los acuíferos en el páramo.

# 1. LIBRERÍAS Y CARGA DE DATOS

library(readxl)
library(dplyr)
library(gt)
library(e1071)

# Carga de datos (Ruta específica del usuario)
Datos_Brutos <- read.csv("C:\\Users\\User\\Downloads\\datos_clima.antisana.csv", check.names = FALSE)
colnames(Datos_Brutos) <- trimws(colnames(Datos_Brutos))

# Selección y limpieza (Variable: Precipitation)
Datos <- Datos_Brutos %>%
  select(any_of(c("Date", "Precipitation"))) %>%
  mutate(Variable_Analisis = as.numeric(gsub(",", ".", as.character(`Precipitation`))))

Variable <- na.omit(Datos$Variable_Analisis)
# Filtro lógico para precipitación (No puede ser negativa, eliminamos errores extremos)
Variable <- Variable[Variable >= 0 & Variable < 500] 

if(length(Variable) == 0) {
  stop("ERROR: No hay datos válidos en la variable seleccionada.")
}

# 2. CÁLCULOS MATEMÁTICOS PARA LA TABLA

N <- length(Variable)

min_val <- min(Variable)
max_val <- max(Variable)
Rango <- max_val - min_val
K <- floor(1 + 3.322 * log10(N)) 
Amplitud <- Rango / K

breaks_table <- seq(min_val, max_val, length.out = K + 1)
breaks_table[length(breaks_table)] <- max_val + 0.0001 

lim_inf_table <- breaks_table[1:K]
lim_sup_table <- breaks_table[2:(K+1)]
MC <- (lim_inf_table + lim_sup_table) / 2

ni <- numeric(K)
for (i in 1:K) {
  if (i < K) {
    ni[i] <- length(Variable[Variable >= lim_inf_table[i] & Variable < lim_sup_table[i]])
  } else {
    ni[i] <- length(Variable[Variable >= lim_inf_table[i] & Variable <= lim_sup_table[i]])
  }
}

hi <- (ni / sum(ni)) * 100 
Ni_asc <- cumsum(ni)
Ni_desc <- rev(cumsum(rev(ni)))
Hi_asc <- cumsum(hi)
Hi_desc <- rev(cumsum(rev(hi)))

TDF_Precip <- data.frame(
  Li = round(lim_inf_table, 2), 
  Ls = round(lim_sup_table, 2), 
  MC = round(MC, 2),            
  ni = ni, 
  hi = round(hi, 2),
  Ni_asc = Ni_asc, 
  Ni_desc = Ni_desc, 
  Hi_asc = round(Hi_asc, 2), 
  Hi_desc = round(Hi_desc, 2)
)

2 Distribución de Frecuencias

A continuación se presenta la tabla de distribución de frecuencias obtenida para los datos de precipitación diaria.

# Totales
totales <- c("TOTAL", "-", "-", sum(ni), round(sum(hi), 2), "-", "-", "-", "-")
TDF_Char <- TDF_Precip %>% mutate(across(everything(), as.character))
TDF_Final <- rbind(TDF_Char, totales)

TDF_Final %>%
  gt() %>%
  tab_header(
    title = md("**DISTRIBUCIÓN DE FRECUENCIAS - ANTISANA**"),
    subtitle = md("Variable: **Precipitación (mm)**")
  ) %>%
  tab_source_note(source_note = "Fuente: Datos Meteorológicos Antisana") %>%
  cols_label(
    Li = "Lím. Inf", Ls = "Lím. Sup", MC = "Marca Clase (Xi)", 
    ni = "ni", hi = "hi (%)", 
    Ni_asc = "Ni (Asc)", Ni_desc = "Ni (Desc)",
    Hi_asc = "Hi (Asc)", Hi_desc = "Hi (Desc)"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style = list(cell_fill(color = "#2E4053"), cell_text(color = "white", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#F2F3F4"), cell_text(weight = "bold", color = "#2E4053")),
    locations = cells_column_labels()
  ) %>%
  tab_options(
    table.border.top.color = "#2E4053",
    table.border.bottom.color = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding = px(6)
  )
DISTRIBUCIÓN DE FRECUENCIAS - ANTISANA
Variable: Precipitación (mm)
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
0.01 10.53 5.27 158 43.17 158 366 43.17 100
10.53 21.06 15.8 89 24.32 247 208 67.49 56.83
21.06 31.58 26.32 56 15.3 303 119 82.79 32.51
31.58 42.1 36.84 33 9.02 336 63 91.8 17.21
42.1 52.63 47.36 16 4.37 352 30 96.17 8.2
52.63 63.15 57.89 9 2.46 361 14 98.63 3.83
63.15 73.67 68.41 3 0.82 364 5 99.45 1.37
73.67 84.2 78.94 0 0 364 2 99.45 0.55
84.2 94.72 89.46 2 0.55 366 2 100 0.55
TOTAL - - 366 100 - - - -
Fuente: Datos Meteorológicos Antisana

3 Análisis Gráfico

Esta sección presenta la visualización de la distribución de los eventos de precipitación.

3.1 Histogramas de Frecuencia

col_gris_azulado <- "#5D6D7E" # Color original mantenido
col_ejes <- "#2E4053"
h_base <- hist(Variable, breaks = "Sturges", plot = FALSE)

# GRÁFICO 1: Histograma Absoluto (Local)
par(mar = c(8, 5, 4, 2)) 
plot(h_base, 
     main = "Gráfica No.1: Distribución de Precipitación en Antisana",
     xlab = "Precipitación Diaria (mm)",
     ylab = "Frecuencia Absoluta (Días)",
     col = col_gris_azulado, border = "white", axes = FALSE,
     ylim = c(0, max(h_base$counts) * 1.1)) 

axis(1, at = round(h_base$breaks, 1), labels = format(round(h_base$breaks, 1), scientific = FALSE), las = 2, cex.axis = 0.7)
axis(2)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted") 

# GRÁFICO 2: Histograma Global
par(mar = c(8, 5, 4, 2))
plot(h_base, 
     main = "Gráfica N°2: Distribución Global de Precipitación",
     xlab = "Precipitación Diaria (mm)",
     ylab = "Total Días con Lluvia",
     col = col_gris_azulado, border = "white", axes = FALSE, 
     ylim = c(0, sum(h_base$counts))) 

axis(1, at = round(h_base$breaks, 1), labels = format(round(h_base$breaks, 1), scientific = FALSE), las = 2, cex.axis = 0.7)
axis(2)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

3.2 Gráficos Porcentuales

h_porc <- h_base
h_porc$counts <- (h_porc$counts / sum(h_porc$counts)) * 100
h_porc$density <- h_porc$counts 

# GRÁFICO 3: Porcentajes (Local)
par(mar = c(8, 5, 4, 2))
plot(h_porc,
     main = "Gráfica N°3: Distribución Porcentual de Precipitación",
     xlab = "Precipitación Diaria (mm)",
     ylab = "Porcentaje (%)",
     col = col_gris_azulado, border = "white", axes = FALSE, freq = TRUE,
     ylim = c(0, max(h_porc$counts)*1.2))

axis(1, at = round(h_base$breaks, 1), labels = format(round(h_base$breaks, 1), scientific = FALSE), las = 2, cex.axis = 0.7)
axis(2)
text(x = h_base$mids, y = h_porc$counts, label = paste0(round(h_porc$counts, 1), "%"), pos = 3, cex = 0.6, col = col_ejes)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted") 

# GRÁFICO 4: Global Porcentual
par(mar = c(8, 5, 4, 2))
plot(h_porc,
     main = "Gráfica No.4: Distribución Porcentual Global (Precipitación)",
     xlab = "Precipitación Diaria (mm)",
     ylab = "% del Total", 
     col = col_gris_azulado, border = "white", axes = FALSE, freq = TRUE,
     ylim = c(0, 100))

axis(1, at = round(h_base$breaks, 1), labels = format(round(h_base$breaks, 1), scientific = FALSE), las = 2, cex.axis = 0.7)
text(x = h_base$mids, y = h_porc$counts, label = paste0(round(h_porc$counts, 1), "%"), pos = 3, cex = 0.6, col = col_ejes)
axis(2)
abline(h=seq(0,100,20), col="#D7DBDD", lty="dotted")

3.3 Diagrama de Caja y Ojivas

# GRÁFICO 5: Boxplot
par(mar = c(5, 5, 4, 2))
boxplot(Variable, horizontal = TRUE, col = col_gris_azulado, 
        main = "Gráfica No.5: Diagrama de Caja de Precipitación (Boxplot)",
        xlab = "Precipitación Diaria (mm)", outline = TRUE, outpch = 19, outcol = "#C0392B", 
        boxwex = 0.5, frame.plot = FALSE, xaxt = "n") 
eje_x_detallado <- pretty(Variable, n = 20) 
axis(1, at = eje_x_detallado, labels = format(eje_x_detallado, scientific = FALSE), cex.axis=0.7, las=2)
grid(nx=NULL, ny=NA, col="lightgray", lty="dotted")

# GRÁFICO 6: Ojivas
par(mar = c(5, 5, 4, 8), xpd = TRUE) 

x_asc <- c(min(breaks_table), breaks_table[2:length(breaks_table)])
y_asc <- c(0, Ni_asc)


x_desc <- c(min(breaks_table), breaks_table[2:length(breaks_table)])
y_desc <- c(Ni_desc, 0) 

x_range <- range(c(x_asc, x_desc))
y_range <- c(0, max(c(y_asc, y_desc)))
col_azul <- "#2E4053"
col_rojo <- "#C0392B"

plot(x_asc, y_asc, type = "o", col = col_azul, lwd=2, pch=19,
     main = "Gráfica No.6: Ojivas Ascendente y Descendente de Precipitación",
     xlab = "Precipitación Diaria (mm)", ylab = "Frecuencia acumulada",
     xlim = x_range, ylim = y_range, axes = FALSE, frame.plot = FALSE, cex.main=0.95)

axis(1, at = round(breaks_table,1), labels = format(round(breaks_table,1), scientific = FALSE), las=2, cex.axis=0.6)
axis(2, at = pretty(y_asc), labels = format(pretty(y_asc), scientific = FALSE))

lines(x_asc, y_desc, type = "o", col = col_rojo, lwd=2, pch=19)

legend("right", legend = c("Ascendente", "Descendente"),
       col = c(col_azul, col_rojo), lty = 1, pch = 19, cex = 0.7, lwd=2,
       inset = c(-0.15, 0), bty="n")
grid()

4 Resumen Estadístico

# CÁLCULO DE INDICADORES 

media_val <- mean(Variable)
mediana_val <- median(Variable)

freq_max <- max(TDF_Precip$ni)
modas_calc <- TDF_Precip$MC[TDF_Precip$ni == freq_max]
moda_txt <- paste(round(modas_calc, 2), collapse = ", ")

rango_txt <- paste0("[", round(min(Variable), 2), "; ", round(max(Variable), 2), "]")
varianza_val <- var(Variable)
sd_val <- sd(Variable)
cv_val <- (sd_val / abs(media_val)) * 100

asimetria_val <- skewness(Variable, type = 2)
curtosis_val <- kurtosis(Variable, type = 2)

vals_atipicos <- boxplot.stats(Variable)$out
num_atipicos <- length(vals_atipicos)

status_atipicos <- if(num_atipicos > 0) {
  min_out <- min(vals_atipicos)
  max_out <- max(vals_atipicos)
  paste0(num_atipicos, " [", round(min_out, 2), "; ", round(max_out, 2), "]")
} else {
  "0 (Sin atípicos)"
}

df_resumen <- data.frame(
  "Variable" = "Precipitación (mm)",
  "Rango" = rango_txt,
  "Media" = media_val,
  "Mediana" = mediana_val,
  "Moda" = moda_txt,
  "Varianza" = varianza_val,
  "Desv_Std" = sd_val,
  "CV_Porc" = cv_val,
  "Asimetria" = asimetria_val,
  "Curtosis" = curtosis_val,
  "Atipicos" = status_atipicos
)

df_resumen %>%
  gt() %>%
  tab_header(
    title = md("**CONCLUSIONES Y ESTADÍSTICOS**"),
    subtitle = "Resumen de Indicadores - Estación Antisana"
  ) %>%
  tab_source_note(source_note = "Autor: Grupo 3") %>%
  fmt_number(columns = c(Media, Mediana, Varianza, Desv_Std, CV_Porc, Curtosis), decimals = 2) %>%
  fmt_number(columns = c(Asimetria), decimals = 4) %>%
  cols_label(
    Variable = "Variable",
    Rango = "Rango Total",
    Media = "Media (X̄)",
    Mediana = "Mediana (Me)",
    Moda = "Moda (Mo)",
    Varianza = "Varianza (S²)",
    Desv_Std = "Desv. Est. (S)",
    CV_Porc = "C.V. (%)",
    Asimetria = "Asimetría (As)",
    Curtosis = "Curtosis (K)",
    Atipicos = "Outliers [Intervalo]"
  ) %>%
  tab_options(
    column_labels.background.color = "#2E4053",
    table.border.top.color = "black",
    table.border.bottom.color = "#2E4053",
    column_labels.border.bottom.color = "#2E4053",
    data_row.padding = px(8)
  ) %>%
  tab_style(
    style = list(cell_text(weight = "bold", color = "white")),
    locations = cells_column_labels()
  )
CONCLUSIONES Y ESTADÍSTICOS
Resumen de Indicadores - Estación Antisana
Variable Rango Total Media (X̄) Mediana (Me) Moda (Mo) Varianza (S²) Desv. Est. (S) C.V. (%) Asimetría (As) Curtosis (K) Outliers [Intervalo]
Precipitación (mm) [0.01; 94.72] 17.10 12.94 5.27 259.70 16.12 94.21 1.3058 2.02 10 [57.83; 94.72]
Autor: Grupo 3

5 Conclusiones

min_txt <- format(min(Variable), scientific = FALSE)
max_txt <- format(max(Variable), scientific = FALSE)

asimetria_val <- skewness(Variable, type = 2)

if (abs(asimetria_val) > 0.5) {
  centro_valor <- format(round(median(Variable), 2), scientific = FALSE)
} else {
  centro_valor <- format(round(mean(Variable), 2), scientific = FALSE)
}

sd_txt <- format(round(sd(Variable), 4), scientific = FALSE)
cv_calc <- (sd(Variable) / abs(mean(Variable))) * 100
tipo_homogeneidad <- if(cv_calc > 30) "heterogénea" else "homogénea"

donde_se_concentra <- if(asimetria_val > 0) "parte media baja" else "parte media alta"

outliers_lista <- boxplot.stats(Variable)$out
num_outliers <- length(outliers_lista)

texto_outliers <- if(num_outliers > 0) {
  paste0("con la presencia de **", num_outliers, " valores atípicos**")
} else {
  "sin valores atípicos significativos"
}


umbral_lluvia_significativa <- 5 

juicio_hidrico <- if(median(Variable) < umbral_lluvia_significativa) {
   
  "moderado o bajo, lo que indica periodos de menor aporte hídrico; esto podría traducirse en un escenario de 'estiaje relativo' o disminución en la recarga de humedales si la tendencia se mantiene a largo plazo"
} else {
   
  "abundante y dinámico, característico de un páramo funcional que garantiza una oferta hídrica constante para la cuenca y favorece el mantenimiento de la cobertura vegetal y los niveles de los reservorios naturales"
}

cat(paste0(
  "## Análisis Descriptivo e Hidrológico\n\n",
   
  "La variable **Precipitación** fluctúa entre **", min_txt, "** y **", max_txt, "** milímetros, ",
  "y sus valores se encuentran alrededor de **", centro_valor, "** mm. ",
  "Presenta una desviación estándar de **", sd_txt, "**, siendo una variable **", tipo_homogeneidad, "** ",
  "(CV: ", round(cv_calc, 2), "%), ",
  "cuyos valores se concentran en la **", donde_se_concentra, "** de la distribución ",
  texto_outliers, "; ",
   
  "**por todo lo anterior, el régimen de precipitaciones se considera ", juicio_hidrico, ".**"
))

5.1 Análisis Descriptivo e Hidrológico

La variable Precipitación fluctúa entre 0.01 y 94.72 milímetros, y sus valores se encuentran alrededor de 12.94 mm. Presenta una desviación estándar de 16.1152, siendo una variable heterogénea (CV: 94.21%), cuyos valores se concentran en la parte media baja de la distribución con la presencia de 10 valores atípicos; por todo lo anterior, el régimen de precipitaciones se considera abundante y dinámico, característico de un páramo funcional que garantiza una oferta hídrica constante para la cuenca y favorece el mantenimiento de la cobertura vegetal y los niveles de los reservorios naturales.