1 Introducción y Metodología

El presente informe estadístico analiza la variable Humedad Relativa registrada en la estación meteorológica del Antisana. Esta variable indica el grado de saturación de vapor de agua en el aire, crucial para la formación de neblina y la regulación térmica del páramo.

# 1. LIBRERÍAS Y CARGA DE DATOS

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

# Carga de datos
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 
Datos <- Datos_Brutos %>%
  select(any_of(c("Date", "Relative Humidity"))) %>%
  mutate(Variable_Analisis = as.numeric(gsub(",", ".", as.character(`Relative Humidity`))) * 100) 
  # NOTA: Se multiplica * 100 para convertir de escala 0-1 a porcentaje

Variable <- na.omit(Datos$Variable_Analisis)

Variable <- Variable[Variable >= 0 & Variable <= 105]

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_Hum <- 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 la humedad relativa.

# Totales
totales <- c("TOTAL", "-", "-", sum(ni), round(sum(hi), 2), "-", "-", "-", "-")
TDF_Char <- TDF_Hum %>% 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: **Humedad Relativa (%)**")
  ) %>%
  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: Humedad Relativa (%)
Lím. Inf Lím. Sup Marca Clase (Xi) ni hi (%) Ni (Asc) Ni (Desc) Hi (Asc) Hi (Desc)
56 60.78 58.39 2 0.55 2 366 0.55 100
60.78 65.56 63.17 15 4.1 17 364 4.64 99.45
65.56 70.33 67.94 18 4.92 35 349 9.56 95.36
70.33 75.11 72.72 21 5.74 56 331 15.3 90.44
75.11 79.89 77.5 16 4.37 72 310 19.67 84.7
79.89 84.67 82.28 20 5.46 92 294 25.14 80.33
84.67 89.44 87.06 35 9.56 127 274 34.7 74.86
89.44 94.22 91.83 60 16.39 187 239 51.09 65.3
94.22 99 96.61 179 48.91 366 179 100 48.91
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 la humedad.

3.1 Histogramas de Frecuencia

col_gris_azulado <- "#5D6D7E"
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 Humedad Relativa en Antisana",
     xlab = "Humedad Relativa (%)",
     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 Humedad Relativa",
     xlab = "Humedad Relativa (%)",
     ylab = "Total Días",
     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 Humedad Relativa",
     xlab = "Humedad Relativa (%)",
     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 (Humedad)",
     xlab = "Humedad Relativa (%)",
     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 Humedad Relativa",
        xlab = "Humedad Relativa (%)", 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 Humedad",
     xlab = "Humedad Relativa (%)", 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_Hum$ni)
modas_calc <- TDF_Hum$MC[TDF_Hum$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" = "Humedad Relativa (%)",
  "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]
Humedad Relativa (%) [56; 99] 89.50 94.00 96.61 118.03 10.86 12.14 −1.1868 0.24 5 [56; 62]
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_saturacion <- 80 

juicio_humedad <- if(median(Variable) < umbral_saturacion) {
   
  "relativamente seco para el contexto de alta montaña, lo que implica una menor presencia de nubosidad baja o neblina constante, favoreciendo la radiación solar directa pero reduciendo la captura hídrica horizontal"
} else {
   
  "altamente saturado, evidenciando la presencia constante de neblina y nubosidad baja, condiciones ideales para la preservación de suelos húmedos y la vegetación de páramo dependiente de la humedad ambiental"
}

cat(paste0(
  "## Análisis Descriptivo e Higrométrico\n\n",
   
  "La variable **Humedad Relativa** fluctúa entre **", min_txt, "** y **", max_txt, "** por ciento, ",
  "y sus valores se encuentran alrededor del **", centro_valor, "** %. ",
  "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 ambiente se considera ", juicio_humedad, ".**"
))

5.1 Análisis Descriptivo e Higrométrico

La variable Humedad Relativa fluctúa entre 56 y 99 por ciento, y sus valores se encuentran alrededor del 94 %. Presenta una desviación estándar de 10.864, siendo una variable homogénea (CV: 12.14%), cuyos valores se concentran en la parte media alta de la distribución con la presencia de 5 valores atípicos; por todo lo anterior, el ambiente se considera altamente saturado, evidenciando la presencia constante de neblina y nubosidad baja, condiciones ideales para la preservación de suelos húmedos y la vegetación de páramo dependiente de la humedad ambiental.