1. IDENTIFICACIÓN Y JUSTIFICACIÓN DE LA VARIABLE

Dirección del Viento se define como una variable cuantitativa continua, ya que se expresa mediante valores numéricos reales (grados sexagesimales) que pueden adoptar cualquier cifra dentro del intervalo de 0° a 360°. Esta continuidad es fundamental en la ingeniería, ya que permite determinar con precisión exacta el origen de las corrientes de aire, lo cual es crítico para el diseño de infraestructuras, la orientación de equipos de captación y el análisis de cargas estructurales en el campo de estudio.

2 CARGA DE DATOS

Importamos el archivo “Dataset_Mundial_Final.xls” desde una ruta local y lo almacenamos en el objeto Datos.
# 1. CARGA DE LIBRERÍAS (Silenciadas para el informe)
suppressPackageStartupMessages(library(tidyverse))
suppressPackageStartupMessages(library(readxl))

# 2. CARGAR EL ARCHIVO
# Mantenemos tu ruta original
Datos <- read_excel("C:/Users/ASUS/OneDrive/Escritorio/ESTADÍSTICA/EXPO/ACTIVIDADES/Dataset_Mundial_Final.xls", 
                    sheet = "Dataset_Mundial_Final")

# 3. VERIFICAR DATOS
str(Datos)
## tibble [58,978 × 29] (S3: tbl_df/tbl/data.frame)
##  $ OBJECTID              : num [1:58978] 2 3 4 5 6 7 8 9 10 11 ...
##  $ code                  : chr [1:58978] "00001-AFG-P" "00002-AFG-P" "00003-AFG-P" "00004-AFG-P" ...
##  $ plant_name            : chr [1:58978] "Badghis Solar Power Plant" "Balkh solar farm" "Behsood solar farm" "Dab Pal 4 solar farm" ...
##  $ country               : chr [1:58978] "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
##  $ operational_status    : chr [1:58978] "cancelled - inferred 4 y" "cancelled - inferred 4 y" "cancelled - inferred 4 y" "shelved - inferred 2 y" ...
##  $ longitude             : num [1:58978] 62.9 67.1 70.4 66.2 65.7 ...
##  $ latitude              : num [1:58978] 35.1 36.7 34.4 33.8 31.7 ...
##  $ elevation             : num [1:58978] 918 359 629 2288 1060 ...
##  $ area                  : num [1:58978] 6.74 10.72 487.73 111.8 1929.96 ...
##  $ size                  : chr [1:58978] "Small" "Small" "Small" "Small" ...
##  $ slope                 : num [1:58978] 7.38 0.49 1.1 6.16 1.23 ...
##  $ slope_type            : chr [1:58978] "Moderado" "Plano o casi plano" "Plano o casi plano" "Moderado" ...
##  $ curvature             : num [1:58978] -0.024 0 0 0.045 -0.005 -0.005 -0.015 0 0 -0.009 ...
##  $ curvature_type        : chr [1:58978] "Superficies cóncavas / Valles" "Superficies planas o intermedias" "Superficies planas o intermedias" "Superficies convexas / Crestas" ...
##  $ aspect                : num [1:58978] 96.8 358.5 36.2 305.8 248.4 ...
##  $ aspect_type           : chr [1:58978] "East" "North" "Northeast" "Northwest" ...
##  $ dist_to_road          : num [1:58978] 7037.1 92.7 112.1 1705.3 115.8 ...
##  $ ambient_temperature   : num [1:58978] 14.4 17.88 21.32 8.86 19.64 ...
##  $ ghi                   : num [1:58978] 5.82 5.58 5.8 6.75 6.62 ...
##  $ humidity              : num [1:58978] 47.7 42.3 36.4 37.3 24.2 ...
##  $ wind_speed            : num [1:58978] 0.039 0.954 0.234 0.943 0.37 ...
##  $ wind_direction        : num [1:58978] 187.5 207.4 255.6 160.3 97.7 ...
##  $ dt_wind               : chr [1:58978] "South" "Southwest" "West" "South" ...
##  $ solar_aptitude        : num [1:58978] 0.72 0.635 0.685 0.659 0.819 0.819 0.818 0.642 0.63 0.374 ...
##  $ solar_aptitude_rounded: num [1:58978] 7 6 7 7 8 8 8 6 6 4 ...
##  $ solar_aptittude_class : chr [1:58978] "Alta" "Alta" "Alta" "Alta" ...
##  $ capacity              : num [1:58978] 32 40 60 3000 100 100 36 50 25 100 ...
##  $ optimal_tilt          : num [1:58978] 30 31 31.1 33 31 ...
##  $ pv_potential          : num [1:58978] 4.61 4.41 4.57 5.42 5.17 ...

3 EXTRAER VARIABLE

Extraemos la variable de dirección del viento, omitimos las celdas en blanco o con valores iguales a cero y verificamos el tamaño muestral para asegurar la representatividad y validez estadística de los datos en el análisis de las corrientes eólicas.
wind_direction <- na.omit(Datos$wind_direction)
wind_direction <- wind_direction[wind_direction > 0]
n_total <- length(wind_direction)

4 TABLA DE DISTRIBUCIÓN DE FRECUENCIA

La tabla de distribución de frecuencias correspondiente a la dirección del viento se elaboró aplicando la regla de Sturges para determinar el número óptimo de agrupaciones. Además, el tamaño o ancho de estas clases se definió a partir del recorrido total que presentan los valores en la muestra.
# 1. CARGAR LIBRERIAS
library(gt)
library(dplyr)

# 2. CALCULOS (Se mantiene igual)
viento_datos <- Datos$wind_direction
viento_datos <- viento_datos[!is.na(viento_datos) & viento_datos != 0]

n_viento <- length(viento_datos)
K_viento <- floor(1 + 3.322 * log10(n_viento))
min_viento <- min(viento_datos)
max_viento <- max(viento_datos)

breaks_viento <- seq(min_viento, max_viento, length.out = K_viento + 1)
lim_inf_v <- breaks_viento[1:K_viento]
lim_sup_v <- breaks_viento[2:(K_viento+1)]
MC_v <- (lim_inf_v + lim_sup_v) / 2

ni_v <- as.vector(table(cut(viento_datos, breaks = breaks_viento, right = FALSE, include.lowest = TRUE)))
hi_v <- (ni_v / sum(ni_v)) * 100 

# 3. CONSTRUCCION DEL DATAFRAME
df_tabla_viento <- data.frame(
  Li = sprintf("%.2f", lim_inf_v), 
  Ls = sprintf("%.2f", lim_sup_v),
  MC = sprintf("%.2f", MC_v),
  ni = as.character(ni_v),
  hi = sprintf("%.2f", hi_v),
  stringsAsFactors = FALSE
)

totales_viento <- c("TOTAL", "-", "-", as.character(sum(ni_v)), sprintf("%.2f", sum(hi_v)))
df_final_viento <- rbind(df_tabla_viento, totales_viento)

# 4. GENERACION DE LA TABLA GT (Usando secuencias Unicode para evitar errores)
# \u00d3 = Ó
# \u00cd = Í
# \u00b0 = °

df_final_viento %>%
  gt() %>%
  tab_header(
    title = md(paste0("**TABLA N\u00b0: 1: DISTRIBUCI\u00d3N DE FRECUENCIAS DE LA DIRECCI\u00d3N DEL VIENTO**"))
  ) %>%
  tab_source_note(source_note = "Fuente: Dataset Mundial Final") %>%
  cols_label(
    Li = "Lim. Inf", 
    Ls = "Lim. Sup", 
    MC = "Marca Clase (Xi)",
    ni = "ni", 
    hi = "hi (%)"
  ) %>%
  cols_align(align = "center", columns = everything()) %>%
  tab_style(
    style = list(cell_fill(color = "white"), cell_text(color = "#4F4F4F", weight = "bold")),
    locations = cells_title()
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#F0F0F0"), cell_text(weight = "bold", color = "#4F4F4F")),
    locations = cells_column_labels()
  ) %>%
  tab_options(
    table.border.top.color = "#D3D3D3",
    table.border.bottom.color = "#D3D3D3",
    column_labels.border.bottom.color = "#D3D3D3",
    data_row.padding = px(6)
  )
TABLA N°: 1: DISTRIBUCIÓN DE FRECUENCIAS DE LA DIRECCIÓN DEL VIENTO
Lim. Inf Lim. Sup Marca Clase (Xi) ni hi (%)
1.40 23.34 12.37 10 0.02
23.34 45.29 34.32 61 0.10
45.29 67.23 56.26 99 0.17
67.23 89.18 78.20 269 0.46
89.18 111.12 100.15 7411 12.60
111.12 133.06 122.09 6373 10.83
133.06 155.01 144.03 4296 7.30
155.01 176.95 165.98 4010 6.82
176.95 198.89 187.92 3091 5.25
198.89 220.84 209.87 4329 7.36
220.84 242.78 231.81 14574 24.77
242.78 264.73 253.75 11813 20.08
264.73 286.67 275.70 2454 4.17
286.67 308.61 297.64 37 0.06
308.61 330.56 319.58 8 0.01
330.56 352.50 341.53 1 0.00
TOTAL - - 58836 100.00
Fuente: Dataset Mundial Final

5 ANÁLISIS GRÁFICO

El análisis gráfico se realiza para visualizar de manera clara y rápida cómo se distribuyen los datos de la dirección del viento. Esta representación permite identificar de forma intuitiva en qué rangos de grados se concentra la mayor parte de los valores y la forma general de la distribución, lo que facilita la detección de direcciones predominantes y complementa la información numérica obtenida en la tabla de frecuencias.

5.1 HISTOGRAMA DE FRECUENCIA

# 1. LIMPIEZA OBLIGATORIA
# if(!is.null(dev.list())) dev.off()

# 2. DEFINIR DATOS Y CÁLCULO EXACTO DE INTERVALOS GLOBALES
Variable <- na.omit(Datos$wind_direction[Datos$wind_direction > 0])

min_v <- min(Variable)
max_v <- max(Variable)
K_global <- floor(1 + 3.322 * log10(length(Variable)))

cortes_globales <- seq(min_v, max_v, length.out = K_global + 1)
cortes_globales[length(cortes_globales)] <- max_v + 0.000001 

col_lila <- "#B0C4DE"

# 3. MÁRGENES 
par(mar = c(6, 4, 3, 1))

# 4. CALCULAR HISTOGRAMA BASE 
h_base <- hist(Variable, breaks = cortes_globales, plot = FALSE, right = FALSE)

# 5. DIBUJAR LA GRÁFICA (Usando Unicode para tildes y símbolos)
# \u00e1 = á | \u00ba = º | \u00f3 = ó | \u00ed = í
plot(h_base, 
     main = "Gr\u00e1fica N\u00ba1: Distribuci\u00f3n Emp\u00edrica de Direcci\u00f3n del Viento",
     xlab = "", 
     ylab = "Frecuencia Absoluta",
     col = col_lila, 
     border = "white", 
     axes = FALSE, 
     ylim = c(0, max(h_base$counts) * 1.1)) 

# 6. EJES Y DISEÑO 
axis(2, las=2, cex.axis=0.7) 
axis(1, at = h_base$breaks, labels = round(h_base$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

# 7. TÍTULO DEL EJE X (Con Unicode para ó y °)
# \u00f3 = ó | \u00b0 = °
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

6 SEGMENTACIÓN

6.1 JUSTIFICACIÓN DE LA SEGMENTACIÓN

Al analizar la distribución empírica global de la Dirección del Viento, se evidencia un comportamiento marcadamente multimodal y asimétrico que imposibilita el ajuste preciso de un único modelo probabilístico para toda la muestra. Por ello, se determinó segmentar estratégicamente los datos en tres subconjuntos utilizando los límites de clase exactos de \(89.2\)° y \(198.9\)°, lo que permite aislar los distintos regímenes físicos del viento: la influencia nororiental (\(0\)° a \(89.2\)°), la transición oriental-sur (\(89.2\)° a \(198.9\)°) y el espectro occidental (\(198.9\)° a \(360\)°). Esta división tripartita reduce la dispersión interna de cada grupo al separar los principales picos de concentración de frecuencias, garantizando que las pruebas de bondad de ajuste y los modelos matemáticos posteriores se adapten con alta precisión a la dinámica real de cada cuadrante direccional, todo ello respetando rigurosamente la continuidad y la naturaleza ordinal de la variable sin distorsionar sus intervalos originales.
# 1. LIMPIEZA OBLIGATORIA
# if(!is.null(dev.list())) dev.off()

# 2. DEFINIR DATOS Y CÁLCULO EXACTO DE INTERVALOS GLOBALES
Variable <- na.omit(Datos$wind_direction[Datos$wind_direction > 0])

# Extraemos la fórmula exacta
min_v <- min(Variable)
max_v <- max(Variable)
K_global <- floor(1 + 3.322 * log10(length(Variable)))

cortes_globales <- seq(min_v, max_v, length.out = K_global + 1)
cortes_globales[length(cortes_globales)] <- max_v + 0.000001 

col_lila <- "#B0C4DE"
col_rojo <- "#C0392B"   

# Definimos los DOS puntos de corte
Corte_1 <- 89.2      
Corte_2 <- 198.9

# 3. MÁRGENES 
par(mar = c(6, 4, 3, 1)) # Pequeño ajuste en el margen superior para el título

# 4. CALCULAR HISTOGRAMA BASE 
h_base <- hist(Variable, breaks = cortes_globales, plot = FALSE, right = FALSE)

# 5. DIBUJAR LA GRÁFICA (Usando Unicode para tildes y símbolos)
# \u00e1=á | \u00ba=º | \u00f3=ó | \u00ed=í
plot(h_base, 
     main = "Gr\u00e1fica N\u00ba1: Distribuci\u00f3n Emp\u00edrica de Direcci\u00f3n del Viento",
     xlab = "", 
     ylab = "Frecuencia Absoluta",
     col = col_lila, 
     border = "white", 
     axes = FALSE, 
     ylim = c(0, max(h_base$counts) * 1.15)) 

# 6. EJES Y DISEÑO 
axis(2, las = 2, cex.axis = 0.7) 
axis(1, at = h_base$breaks, labels = round(h_base$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

# Título Eje X (Con Unicode para ó y °)
# \u00f3=ó | \u00b0=°
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

# 7. LAS DOS LÍNEAS DE CORTE ESTRATÉGICAS
abline(v = c(Corte_1, Corte_2), col = col_rojo, lwd = 3, lty = 2)

# Leyenda con ambos cortes (Con Unicode para °)
# \u00b0=°
legend("topright", 
       legend = c(paste("Corte 1:", Corte_1, "\u00b0"), 
                  paste("Corte 2:", Corte_2, "\u00b0")), 
       col = col_rojo, lty = 2, lwd = 3, bty = "n", cex = 0.8)

6.2 PRIMER SEGMENTO

# 1. LIMPIEZA OBLIGATORIA
# if(!is.null(dev.list())) dev.off()

# 2. CALCULAR LOS CORTES GLOBALES EXACTOS
Variable_Completa <- na.omit(Datos$wind_direction[Datos$wind_direction > 0])
min_v <- min(Variable_Completa)
max_v <- max(Variable_Completa)
K_global <- floor(1 + 3.322 * log10(length(Variable_Completa)))

cortes_globales <- seq(min_v, max_v, length.out = K_global + 1)
cortes_globales[length(cortes_globales)] <- max_v + 0.000001 

# 3. EXTRAER SOLO LOS CORTES HASTA 89.2 (Nuevo segmento)
cortes_seg_nuevo <- cortes_globales[cortes_globales <= (89.2 + 0.1)]
Segmento_Nuevo <- Variable_Completa[Variable_Completa <= max(cortes_seg_nuevo)]

# 4. MÁRGENES Y CONFIGURACIÓN
par(mar = c(6, 4, 3, 1))
col_lila <- "#B0C4DE"

# 5. CALCULAR HISTOGRAMA
h_seg_nuevo <- hist(Segmento_Nuevo, breaks = cortes_seg_nuevo, plot = FALSE, right = FALSE)

# 6. DIBUJAR LA GRÁFICA (Usando Unicode para evitar el error de traducción)
# \u00e1=á | \u00ba=º | \u00b0=°
plot(h_seg_nuevo, 
     main = "Gr\u00e1fica N\u00ba 2: Sector Nororiental (0\u00b0 a 89.2\u00b0)",
     xlab = "", 
     ylab = "Frecuencia Absoluta",
     col = col_lila, 
     border = "white", 
     axes = FALSE, 
     ylim = c(0, max(h_seg_nuevo$counts) * 1.1), 
     xlim = c(min_v, max(cortes_seg_nuevo))) 

# 7. EJES Y DISEÑO 
axis(2, las=2, cex.axis=0.7) 
axis(1, at = h_seg_nuevo$breaks, labels = round(h_seg_nuevo$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

# \u00f3=ó | \u00b0=°
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

6.3 SEGUNDO SEGMENTO

# 1. LIMPIEZA OBLIGATORIA
# if(!is.null(dev.list())) dev.off()

# 2. CALCULAR LOS CORTES GLOBALES EXACTOS
Variable_Completa <- na.omit(Datos$wind_direction[Datos$wind_direction > 0])
min_v <- min(Variable_Completa)
max_v <- max(Variable_Completa)
K_global <- floor(1 + 3.322 * log10(length(Variable_Completa)))

cortes_globales <- seq(min_v, max_v, length.out = K_global + 1)
cortes_globales[length(cortes_globales)] <- max_v + 0.000001 

# 3. EXTRAER SOLO LOS CORTES DEL SEGMENTO (89.2 a 198.9)
cortes_seg_medio <- cortes_globales[cortes_globales >= (89.2 - 0.1) & cortes_globales <= (198.9 + 0.1)]
Segmento_Medio <- Variable_Completa[Variable_Completa > min(cortes_seg_medio) & Variable_Completa <= max(cortes_seg_medio)]

# 4. MÁRGENES Y CONFIGURACIÓN
par(mar = c(6, 4, 3, 1))
col_lila <- "#B0C4DE"

# 5. CALCULAR HISTOGRAMA 
h_seg_medio <- hist(Segmento_Medio, breaks = cortes_seg_medio, plot = FALSE, right = FALSE)

# 6. DIBUJAR LA GRÁFICA (Usando Unicode para evitar errores de traducción)
# \u00e1=á | \u00ba=º | \u00f3=ó | \u00b0=°
plot(h_seg_medio, 
     main = "Gr\u00e1fica N\u00ba 3: Transici\u00f3n Oriental - Sur (89.2\u00b0 a 198.9\u00b0)",
     xlab = "", 
     ylab = "Frecuencia Absoluta",
     col = col_lila, 
     border = "white", 
     axes = FALSE, 
     ylim = c(0, max(h_seg_medio$counts) * 1.1), 
     xlim = c(min(cortes_seg_medio), max(cortes_seg_medio))) 

# 7. EJES Y DISEÑO 
axis(2, las=2, cex.axis=0.7) 
axis(1, at = h_seg_medio$breaks, labels = round(h_seg_medio$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

# \u00f3=ó | \u00b0=°
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

6.4 TERCER SEGMENTO

# 1. LIMPIEZA OBLIGATORIA
# if(!is.null(dev.list())) dev.off()

# 2. CALCULAR LOS CORTES GLOBALES EXACTOS
Variable_Completa <- na.omit(Datos$wind_direction[Datos$wind_direction > 0])
min_v <- min(Variable_Completa)
max_v <- max(Variable_Completa)
K_global <- floor(1 + 3.322 * log10(length(Variable_Completa)))

cortes_globales <- seq(min_v, max_v, length.out = K_global + 1)
cortes_globales[length(cortes_globales)] <- max_v + 0.000001 

# 3. EXTRAER SOLO LOS CORTES DEL TERCER SEGMENTO (Desde 198.9 hasta el final)
cortes_seg_final <- cortes_globales[cortes_globales >= (198.9 - 0.1)]
Segmento_Final <- Variable_Completa[Variable_Completa > min(cortes_seg_final)]

# 4. MÁRGENES Y CONFIGURACIÓN
par(mar = c(6, 4, 3, 1))
col_lila <- "#B0C4DE"

# 5. CALCULAR HISTOGRAMA 
h_seg_final <- hist(Segmento_Final, breaks = cortes_seg_final, plot = FALSE, right = FALSE)

# 6. DIBUJAR LA GRÁFICA (Usando Unicode para evitar el error de traducción)
# \u00e1=á | \u00ba=º | \u00b0=°
plot(h_seg_final, 
     main = "Gr\u00e1fica N\u00ba 4: Hemisferio Occidental (198.9\u00b0 a 360\u00b0)",
     xlab = "", 
     ylab = "Frecuencia Absoluta",
     col = col_lila, 
     border = "white", 
     axes = FALSE, 
     ylim = c(0, max(h_seg_final$counts) * 1.1), 
     xlim = c(min(cortes_seg_final), max(cortes_seg_final))) 

# 7. EJES Y DISEÑO 
axis(2, las=2, cex.axis=0.7) 
axis(1, at = h_seg_final$breaks, labels = round(h_seg_final$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

# \u00f3=ó | \u00b0=°
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

7 ESTRATIFICACIÓN DEL MODELO

7.1 ANÁLISIS DEL PRIMER SEGMENTO

Definida la segmentación general, el análisis estadístico inicia con el primer estrato direccional, comprendido entre los \(0\)° y \(89.2\)°. Aislar este subconjunto permite evaluar su comportamiento empírico de forma independiente, facilitando la posterior aplicación de las pruebas de bondad de ajuste para identificar el modelo teórico específico que mejor describa la dinámica de este primer cuadrante.
# 1. CARGA DE LIBRERÍAS (Silenciando conflictos de máscara)
# if(!is.null(dev.list())) dev.off() 
suppressPackageStartupMessages(library(MASS))

# 2. DATOS Y CORTES
Variable_Completa <- na.omit(Datos$wind_direction[Datos$wind_direction > 0])
min_v <- min(Variable_Completa)
max_v <- max(Variable_Completa)
K_global <- floor(1 + 3.322 * log10(length(Variable_Completa)))
cortes_globales <- seq(min_v, max_v, length.out = K_global + 1)
cortes_globales[length(cortes_globales)] <- max_v + 0.000001 

cortes_seg_nuevo <- cortes_globales[cortes_globales <= (89.2 + 0.1)]
Segmento_Nuevo <- Variable_Completa[Variable_Completa <= max(cortes_seg_nuevo)]

# 3. AJUSTE WEIBULL REFLEJADA (Silenciando NaNs internos)
C_Constante <- 90 
Datos_Reflejados <- (C_Constante - Segmento_Nuevo) + 0.01

# suppressWarnings evita que salgan los avisos de NaNs en el PDF final
ajuste_weibull <- suppressWarnings(fitdistr(Datos_Reflejados[Datos_Reflejados > 0], "weibull"))
shape_ref <- ajuste_weibull$estimate["shape"]
scale_ref <- ajuste_weibull$estimate["scale"]

# 4. DIBUJAR GRÁFICA (Unicode para tildes y símbolos)
par(mar = c(6, 4, 3, 1))
h_seg_nuevo <- hist(Segmento_Nuevo, breaks = cortes_seg_nuevo, plot = FALSE, right = FALSE)

plot(h_seg_nuevo, freq = FALSE, 
     main = "Gr\u00e1fica N\u00ba 5: Ajuste Weibull Reflejado (Sector Nororiental)",
     xlab = "", ylab = "Densidad de Probabilidad",
     col = "#B0C4DE", border = "white", axes = FALSE)

# Ejes y Diseño
axis(2, las=2, cex.axis=0.7) 
axis(1, at = h_seg_nuevo$breaks, labels = round(h_seg_nuevo$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

# 5. CURVA WEIBULL REFLEJADA
x_curva <- seq(min(cortes_seg_nuevo), max(cortes_seg_nuevo), length.out = 100)
y_curva <- dweibull((C_Constante - x_curva) + 0.01, shape = shape_ref, scale = scale_ref)
lines(x_curva, y_curva, col = "#C0392B", lwd = 3)

7.1.1 TEST DE PEARSON Y CHI CUADRADO

# --- TEST PARA SEGMENTO 1 (Weibull Reflejada) ---
n1 <- length(Segmento_Nuevo)
K1 <- length(cortes_seg_nuevo) - 1
probs1 <- numeric(K1)

for(i in 1:K1) {  
  lim_inf_ref <- C_Constante - cortes_seg_nuevo[i+1] + 0.001  
  lim_sup_ref <- C_Constante - cortes_seg_nuevo[i] + 0.001    
  probs1[i] <- pweibull(lim_sup_ref, shape = shape_ref, scale = scale_ref) - 
               pweibull(lim_inf_ref, shape = shape_ref, scale = scale_ref)
}

probs1 <- probs1 / sum(probs1)
n_base <- 100

Fo1 <- as.vector(table(cut(Segmento_Nuevo, breaks = cortes_seg_nuevo, right = FALSE))) * (n_base / n1)
Fe1 <- probs1 * n_base

chi1 <- sum((Fo1 - Fe1)^2 / Fe1)
crit1 <- qchisq(0.99, K1 - 1 - 2) 

if(is.na(crit1) | crit1 <= 0) crit1 <- 3.84 

res1 <- if(chi1 < crit1) "APROBADO" else "RECHAZADO"
pear1 <- cor(Fo1, Fe1) * 100

cat("SEGMENTO 1 (Weibull Reflejada):\n")
## SEGMENTO 1 (Weibull Reflejada):
cat("Resultado Chi-cuadrado:", res1, "\n")
## Resultado Chi-cuadrado: APROBADO
cat("Chi-calculado:", round(chi1, 2), "| Chi-cr\u00edtico:", round(crit1, 2), "\n")
## Chi-calculado: 4.49 | Chi-crítico: 6.63
cat("Correlaci\u00f3n de Pearson:", round(pear1, 2), "%\n")
## Correlación de Pearson: 99.32 %

7.2 ANÁLISIS DEL SEGUNDO SEGMENTO

Para este segmento, se utilizó el modelo Weibull Estándar porque los datos en este rango presentan una asimetría marcada hacia un sector específico. Este modelo es el estándar en ingeniería eólica para representar vientos que tienen un pico de frecuencia definido, permitiendo capturar con precisión la tendencia direccional hacia el sur de la planta.
# 1. AJUSTE DE PARÁMETROS (Modelo Weibull)
library(MASS)

# Desplazamos los datos al origen
desplazamiento2 <- min(cortes_seg_medio)
# Sumamos 0.01 para evitar ceros estrictos y que no salgan NaNs
Datos_Weibull2 <- (Segmento_Medio - desplazamiento2) + 0.01

# Ajustamos silenciando los avisos internos para un Knit limpio
ajuste_weibull2 <- suppressWarnings(fitdistr(Datos_Weibull2[Datos_Weibull2 > 0], "weibull"))
shape_seg2  <- ajuste_weibull2$estimate["shape"]
scale_seg2 <- ajuste_weibull2$estimate["scale"]

# 2. DIBUJAR LA GRÁFICA (Unicode para evitar error de traducción)
par(mar = c(6, 4, 3, 1))
plot(h_seg_medio, 
     freq = FALSE, 
     main = "Gr\u00e1fica N\u00ba 3: Ajuste Weibull (89.2\u00b0 a 198.9\u00b0)",
     xlab = "", ylab = "Densidad",
     col = "#B0C4DE", border = "white", axes = FALSE)

# 3. CURVA TEÓRICA WEIBULL
x_curva <- seq(min(cortes_seg_medio), max(cortes_seg_medio), length.out = 100)
# Ajustamos la curva con el mismo offset de 0.01
y_curva <- dweibull((x_curva - desplazamiento2) + 0.01, shape = shape_seg2, scale = scale_seg2)
lines(x_curva, y_curva, col = "#C0392B", lwd = 3)

# 4. EJES Y DISEÑO
axis(2, las = 2, cex.axis = 0.7) 
axis(1, at = h_seg_medio$breaks, labels = round(h_seg_medio$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx = NA, ny = NULL, col = "#D7DBDD", lty = "dotted")

# \u00f3=ó | \u00b0=°
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

legend("topright", legend = "Modelo Weibull", col = "#C0392B", lwd = 3, bty = "n", cex = 0.8)

7.2.1 TEST DE PEARSON Y CHI-CUADRADO

# --- TEST PARA SEGMENTO 2 (Distribución Weibull) ---
n2 <- length(Segmento_Medio)
K2 <- length(cortes_seg_medio) - 1
probs2 <- numeric(K2)

# Cálculo de probabilidades (Usando desplazamiento)
for(i in 1:K2) {  
  probs2[i] <- pweibull(cortes_seg_medio[i+1] - desplazamiento2, shape = shape_seg2, scale = scale_seg2) - 
               pweibull(cortes_seg_medio[i] - desplazamiento2, shape = shape_seg2, scale = scale_seg2)
}

probs2 <- probs2 / sum(probs2)
n_base <- 100

Fo2 <- as.vector(table(cut(Segmento_Medio, breaks = cortes_seg_medio, right = FALSE))) * (n_base / n2)
Fe2 <- probs2 * n_base

chi2 <- sum((Fo2 - Fe2)^2 / Fe2)
# Grados de libertad: K - 1 - 2
crit2 <- qchisq(0.99, K2 - 1 - 2) 

if(is.na(crit2) | crit2 <= 0) crit2 <- 3.84 

res2 <- if(chi2 < crit2) "APROBADO" else "RECHAZADO"
pear2 <- cor(Fo2, Fe2) * 100

cat("SEGMENTO 2 (Distribuci\u00f3n Weibull):\n")
## SEGMENTO 2 (Distribución Weibull):
cat("Resultado Chi-cuadrado:", res2, "\n")
## Resultado Chi-cuadrado: APROBADO
cat("Chi-calculado:", round(chi2, 2), "| Chi-cr\u00edtico:", round(crit2, 2), "\n")
## Chi-calculado: 8.73 | Chi-crítico: 9.21
cat("Correlaci\u00f3n de Pearson:", round(pear2, 2), "%\n")
## Correlación de Pearson: 93.36 %

7.3 ANÁLISIS DEL TERCER SEGMENTO

En este segmento, se utilizó el modelo de distribución Normal porque los datos muestran un comportamiento simétrico y centralizado. Al presentar una forma de campana de Gauss, este modelo es el más eficiente para describir vientos estables que se agrupan alrededor de un valor promedio en el sector oeste.
# 1. AJUSTE DE PARÁMETROS (Modelo Normal)
library(MASS)
# Calculamos la media y desviación estándar para el último bloque
ajuste_normal3 <- fitdistr(Segmento_Final, "normal")
media_seg3 <- ajuste_normal3$estimate["mean"]
sd_seg3    <- ajuste_normal3$estimate["sd"]

# 2. DIBUJAR LA GRÁFICA (Unicode para evitar error de traducción)
# \u00e1=á | \u00ba=º | \u00b0=°
par(mar = c(6, 4, 3, 1))
plot(h_seg_final, 
     freq = FALSE, 
     main = "Gr\u00e1fica N\u00ba 4: Ajuste Normal (198.9\u00b0 a 360\u00b0)",
     xlab = "", ylab = "Densidad",
     col = "#B0C4DE", border = "white", axes = FALSE)

# 3. CURVA TEÓRICA NORMAL
x_curva <- seq(min(cortes_seg_final), max(cortes_seg_final), length.out = 100)
y_curva <- dnorm(x_curva, mean = media_seg3, sd = sd_seg3)
lines(x_curva, y_curva, col = "#C0392B", lwd = 3)

# 4. EJES Y DISEÑO
axis(2, las=2, cex.axis=0.7) 
axis(1, at = h_seg_final$breaks, labels = round(h_seg_final$breaks, 1), las = 2, cex.axis = 0.6)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

# \u00f3=ó | \u00b0=°
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.8)

legend("topright", legend = "Modelo Normal", col = "#C0392B", lwd = 3, bty = "n", cex = 0.8)

7.3.1 TEST DE PEARSON Y CHI-CUADRADO

# --- TEST PARA SEGMENTO 3 (Distribución Normal) ---
n3 <- length(Segmento_Final)
K3 <- length(cortes_seg_final) - 1
probs3 <- numeric(K3)

for(i in 1:K3) {  
  probs3[i] <- pnorm(cortes_seg_final[i+1], mean = media_seg3, sd = sd_seg3) - 
               pnorm(cortes_seg_final[i], mean = media_seg3, sd = sd_seg3)
}

probs3 <- probs3 / sum(probs3)
n_base <- 100

Fo3 <- as.vector(table(cut(Segmento_Final, breaks = cortes_seg_final, right = FALSE))) * (n_base / n3)
Fe3 <- probs3 * n_base

chi3 <- sum((Fo3 - Fe3)^2 / Fe3)
# Grados de libertad para Normal: K - 1 - 2
crit3 <- qchisq(0.99, K3 - 1 - 2) 

if(is.na(crit3) | crit3 <= 0) crit3 <- 3.84 

res3 <- if(chi3 < crit3) "APROBADO" else "RECHAZADO"
pear3 <- cor(Fo3, Fe3) * 100

cat("SEGMENTO 3 (Distribuci\u00f3n Normal):\n")
## SEGMENTO 3 (Distribución Normal):
cat("Resultado Chi-cuadrado:", res3, "\n")
## Resultado Chi-cuadrado: APROBADO
cat("Chi-calculado:", round(chi3, 2), "| Chi-cr\u00edtico:", round(crit3, 2), "\n")
## Chi-calculado: 1.86 | Chi-crítico: 13.28
cat("Correlaci\u00f3n de Pearson:", round(pear3, 2), "%\n")
## Correlación de Pearson: 99.97 %

8 MODELO HÍBRIDO

# 1. CONFIGURACIÓN Y COLORES
# if(!is.null(dev.list())) dev.off()
par(mar = c(6, 4, 4, 2))

col_seg1 <- "#AED6F1" # Azul
col_seg2 <- "#A9DFBF" # Verde
col_seg3 <- "#FAD7A0" # Naranja

# 2. CÁLCULO DE PROPORCIONES
n_total <- length(Variable_Completa)
prop1 <- length(Segmento_Nuevo) / n_total
prop2 <- length(Segmento_Medio) / n_total
prop3 <- length(Segmento_Final) / n_total

# 3. DIBUJAR HISTOGRAMA GLOBAL
h_global <- hist(Variable_Completa, breaks = cortes_globales, plot = FALSE)
colores_barras <- ifelse(h_global$breaks[-1] <= 89.2, col_seg1,
                  ifelse(h_global$breaks[-1] <= 198.9, col_seg2, col_seg3))

# \u00e1=á | \u00ba=º | \u00ed=í | \u00f3=ó
plot(h_global, freq = FALSE, col = colores_barras, border = "white",
     main = "Gr\u00e1fica N\u00ba 5: Modelo H\u00edbrido Escalado de Direcci\u00f3n del Viento",
     xlab = "", ylab = "Densidad de Probabilidad",
     axes = FALSE, ylim = c(0, max(h_global$density) * 1.2))

# 4. LÍNEAS DIVISORIAS
abline(v = c(89.2, 198.9), col = "gray40", lty = "dashed", lwd = 2)

# 5. DIBUJAR LAS TRES CURVAS (Escaladas)

# --- Curva 1: Weibull Reflejada ---
x1 <- seq(min_v, 89.2, length.out = 100)
y1 <- dweibull(90 - x1, shape = shape_ref, scale = scale_ref) * prop1
lines(x1, y1, col = "blue4", lwd = 3)

# --- Curva 2: Weibull Estándar ---
x2 <- seq(89.2, 198.9, length.out = 100)
y2 <- dweibull(x2 - desplazamiento2, shape = shape_seg2, scale = scale_seg2) * prop2
lines(x2, y2, col = "darkgreen", lwd = 3)

# --- Curva 3: Normal ---
x3 <- seq(198.9, 360, length.out = 100)
y3 <- dnorm(x3, mean = media_seg3, sd = sd_seg3) * prop3
lines(x3, y3, col = "darkorange3", lwd = 3)

# 6. EJES Y DISEÑO
axis(2, las=2, cex.axis=0.7) 
axis(1, at = round(cortes_globales, 1), labels = round(cortes_globales, 1), las = 2, cex.axis = 0.6)
grid(nx=NA, ny=NULL, col="#D7DBDD", lty="dotted")

# \u00f3=ó | \u00b0=°
mtext("Direcci\u00f3n del Viento (\u00b0)", side = 1, line = 4.5, cex = 0.9)

# Leyenda corregida (\u00e1=á | \u00ed=í)
legend("topright", 
       legend = c("S1: Weibull Reflejada", "S2: Weibull Est\u00e1ndar", "S3: Normal"),
       col = c("blue4", "darkgreen", "darkorange3"), 
       lwd = 3, bty = "n", cex = 0.8, title = "Modelos H\u00edbridos")

9 TABLA RESUMEN DE BONDAD DEL AJUSTE

# 1. CARGAR LIBRERIAS
library(MASS)
library(knitr)

# --- GENERACION DE LA TABLA RESUMEN (3 SEGMENTOS) ---
# \u00f3 = ó
resumen_final <- data.frame(
  "Segmento" = c("S1: Nororiental (Weibull Ref)", 
                 "S2: Transici\u00f3n E-S (Weibull)", 
                 "S3: Occidental (Normal)"),
  "Pearson (%)" = c(round(pear1, 2), round(pear2, 2), round(pear3, 2)),
  "Chi-Calc" = c(round(chi1, 2), round(chi2, 2), round(chi3, 2)),
  "Chi-Crit" = c(round(crit1, 2), round(crit2, 2), round(crit3, 2)),
  "Estado" = c(res1, res2, res3)
)

# Imprimir tabla con formato kable
# \u00f3 = ó | \u00ed = í
kable(resumen_final, 
      format = "markdown", 
      align = "lcccc",
      caption = "Tabla No. 2: Resumen de validaci\u00f3n de los modelos de probabilidad (Modelo H\u00edbrido)")
Tabla No. 2: Resumen de validación de los modelos de probabilidad (Modelo Híbrido)
Segmento Pearson…. Chi.Calc Chi.Crit Estado
S1: Nororiental (Weibull Ref) 99.32 4.49 6.63 APROBADO
S2: Transición E-S (Weibull) 93.36 8.73 9.21 APROBADO
S3: Occidental (Normal) 99.97 1.86 13.28 APROBADO

10 CÁLCULO DE PROBABILIDADES

Habiendo validado que el comportamiento de la orientación de incidencia solar se ajusta a un modelo híbrido estratificado, procedemos a proyectar escenarios operativos para la optimización de la planta:
\(Pregunta\) \(1\) : ¿Cuál es la probabilidad de que el viento sople desde el Sur/Sureste (entre \(120\)° y \(198.9\)°), ayudando a enfriar los paneles solares para que no pierdan eficiencia por el calor del mediodía?
\(Pregunta\) \(2\): Si instalamos \(120\) sensores de ráfagas, ¿cuántos de ellos detectarán vientos provenientes del Oeste/Noroeste (entre \(250\)° y \(320\)°), los cuales podrían obligar a poner los paneles en ‘modo de protección’ para evitar que se dañen
# --- ANÁLISIS DE ESCENARIOS: SEGMENTOS 2 Y 3 (Ejes Ajustados) ---

# 1. Definir pesos de los segmentos 2 y 3
n_sub <- length(Segmento_Medio) + length(Segmento_Final)
w2 <- length(Segmento_Medio) / n_sub
w3 <- length(Segmento_Final) / n_sub

# --- CÁLCULOS MATEMÁTICOS ---
prob_p1 <- (pweibull(198.9 - desplazamiento2, shape_seg2, scale_seg2) - 
            pweibull(120 - desplazamiento2, shape_seg2, scale_seg2)) * w2

prob_p2 <- (pnorm(320, media_seg3, sd_seg3) - 
            pnorm(250, media_seg3, sd_seg3)) * w3
sensores_p2 <- round(prob_p2 * 120)

# --- GRÁFICA ANALÍTICA ---
f_hibrida_S2_S3 <- function(x) {
  y <- numeric(length(x))
  idx2 <- x <= 198.9
  y[idx2] <- dweibull(x[idx2] - desplazamiento2, shape_seg2, scale_seg2) * w2
  idx3 <- x > 198.9
  y[idx3] <- dnorm(x[idx3], mean = media_seg3, sd = sd_seg3) * w3
  return(y)
}

par(mar = c(5, 5, 4, 2))

# USANDO UNICODE: \u00e1 = á | \u00f3 = ó | \u00b0 = °
curve(f_hibrida_S2_S3, from = 89.2, to = 360, lwd = 3, col = "#2E4053",
      main = "Gr\u00e1fica No. 8: Riesgos y Eficiencia en Planta Solar",
      xlab = "Direcci\u00f3n del Viento (\u00b0)", ylab = "Densidad", 
      axes = FALSE, ylim = c(0, max(f_hibrida_S2_S3(seq(90,360,1))) * 1.5))

# Pintar P1 (Verde - Enfriamiento)
x_p1 <- seq(120, 198.9, length.out = 100)
polygon(c(120, x_p1, 198.9), c(0, f_hibrida_S2_S3(x_p1), 0), col = rgb(0.1, 0.6, 0.1, 0.5), border = NA)

# Pintar P2 (Rojo/Naranja - Seguridad)
x_p2 <- seq(250, 320, length.out = 100)
polygon(c(250, x_p2, 320), c(0, f_hibrida_S2_S3(x_p2), 0), col = rgb(0.8, 0.2, 0.1, 0.5), border = NA)

# --- EJES CON NÚMEROS MÁS PEQUEÑOS (cex.axis = 0.7) ---
axis(1, at = seq(90, 360, 30), cex.axis = 0.7) 
axis(2, las = 2, cex.axis = 0.7)               
grid(lty = "dotted")

# Leyenda con Unicode (\u00ed = í)
legend("topright", bty = "n", cex = 0.7,
       legend = c("Modelo H\u00edbrido (S2-S3)", 
                  paste0("Enfriamiento (", round(prob_p1*100,2), "%)"), 
                  paste0("Seguridad (", round(prob_p2*100,2), "%)")),
       col = c("#2E4053", rgb(0.1, 0.6, 0.1, 0.5), rgb(0.8, 0.2, 0.1, 0.5)), 
       pch = c(NA, 15, 15), lty = c(1, NA, NA))

\(Respuesta\) \(1\) : Se determinó una probabilidad del \(23.15\)% de que el viento sople desde el sector sur (\(120\)° a \(198.9\)°). Este flujo es clave para el proyecto, ya que favorece el enfriamiento natural de los paneles, ayudando a que no pierdan eficiencia por exceso de calor durante las horas de mayor radiación.
\(Respuesta\) \(2\) : Existe una probabilidad del \(15.87\)% de vientos provenientes del sector oeste (\(250\)° a \(320\)°), lo que representa una zona de riesgo estructural. Por lo tanto, de los \(120\) sensores proyectados, se estima que \(19\) unidades deberán configurarse con protocolos de seguridad y anclaje para proteger los paneles de posibles ráfagas fuertes.

11 TEOREMA DE LÍMITE CENTRAL

El TLC establece que, dada una muestra suficientemente grande (\(n\) > \(30\)), la distribución de las medias muestrales seguirá una distribución Normal. Esto nos permite estimar la Media Poblacional (\(\mu\)) verdadera utilizando intervalos de confianza.Los postulados de confianza empírica sugieren:
\(P(\bar{x} - E < \mu < \bar{x} + E) \approx 68\%\)
\(P(\bar{x} - 2E < \mu < \bar{x} + 2E) \approx 95\%\)
\(P(\bar{x} - 3E < \mu < \bar{x} + 3E) \approx 99\%\)
Donde el Margen de Error (E) se define como: \[E = \frac{\sigma}{\sqrt{n}}\]
# 1. CARGAR LIBRERIAS
library(gt)
library(dplyr)

# 2. CALCULO DE ESTADISTICOS (Sobre la variable global)
x_bar <- mean(Variable_Completa)
sigma_muestral <- sd(Variable_Completa)
n_tlc <- length(Variable_Completa)

# 3. CALCULO DEL ERROR ESTANDAR Y MARGEN AL 95%
error_est <- sigma_muestral / sqrt(n_tlc)
margen_error_95 <- 2 * error_est

# 4. INTERVALO DE CONFIANZA
lim_inf_tlc <- x_bar - margen_error_95
lim_sup_tlc <- x_bar + margen_error_95

# 5. CONSTRUCCION DE LA TABLA RESUMEN (Usando Unicode para evitar errores)
# \u00f3 = ó | \u00b0 = °
tabla_tlc_data <- data.frame(
  Parametro = "Direcci\u00f3n del Viento Promedio (\u00b0)",
  Lim_Inferior = lim_inf_tlc,
  Media_Muestral = x_bar,
  Lim_Superior = lim_sup_tlc,
  Error_Estandar = paste0("+/- ", sprintf("%.4f", margen_error_95)),
  Confianza = "95% (2*E)"
)

# 6. GENERACION DE LA TABLA VISUAL
# \u00d3 = Ó | \u00e1 = á | \u00ed = í
tabla_tlc_final <- tabla_tlc_data %>%
  gt() %>%
  tab_header(
    title = md("**ESTIMACI\u00d3N DE LA MEDIA POBLACIONAL**"),
    subtitle = "Direcci\u00f3n del Viento - Aplicaci\u00f3n del Teorema del L\u00edmite Central"
  ) %>%
  cols_label(
    Parametro = "Par\u00e1metro",
    Lim_Inferior = "L\u00edmite Inferior",
    Media_Muestral = "Media Calculada",
    Lim_Superior = "L\u00edmite Superior",
    Error_Estandar = "Error Estimado"
  ) %>%
  fmt_number(
    columns = c(Lim_Inferior, Media_Muestral, Lim_Superior),
    decimals = 4
  ) %>%
  tab_style(
    style = list(cell_fill(color = "#EBF5FB"), cell_text(color = "#1A5276", weight = "bold")),
    locations = cells_body(columns = Media_Muestral)
  )

# Visualizar la tabla
tabla_tlc_final
ESTIMACIÓN DE LA MEDIA POBLACIONAL
Dirección del Viento - Aplicación del Teorema del Límite Central
Parámetro Límite Inferior Media Calculada Límite Superior Error Estimado Confianza
Dirección del Viento Promedio (°) 192.9495 193.4319 193.9142 +/- 0.4823 95% (2*E)

12 CONCLUSIÓN

Gracias a la robustez de este análisis y a la aplicación del Teorema del Límite Central, podemos afirmar con un \(95\%\) de confianza que la media aritmética poblacional de la dirección del viento se encuentra en el intervalo de \(\mu \in [192.9495^\circ ; 193.9142^\circ]\). Este resultado (\(\mu = 193.4319^\circ \pm 0.4823^\circ\)) demuestra una alta precisión en la caracterización del flujo eólico, indicando que el valor promedio global se mantiene estable en una dirección que favorece la operatividad térmica de los paneles. Lo anterior proporciona una base estadística sólida para la toma de decisiones gerenciales en la planificación del proyecto solar, minimizando la incertidumbre operativa y optimizando la resistencia de las estructuras en el área de estudio.