0. Librerías

library(readr)
library(dplyr)
library(knitr)
library(kableExtra)
library(ggplot2)
library(e1071)

1. Leer variables

variables <- read.csv("C:/Users/dellh/Downloads/GlobalWeatherRepository.csv")

2. Extraer y Depuración de la Variable

UV <- na.omit(variables$uv_index)
n_total <- length(UV)

3. TDF de la variable radiación Ultravioleta

valor_min <- min(UV)
valor_max <- max(UV)

# Crear los límites numéricos originales

Li2 <- seq(floor(valor_min/2)*2, ceiling(valor_max/2)*2 - 2, by = 2)
Ls2 <- Li2 + 2
MC2 <- (Li2 + Ls2)/2

# Calcular frecuencias numéricas absolutas y relativas
ni2 <- numeric(length(Li2))
for(i in 1:length(Li2)){
  if(i == length(Li2)){
    ni2[i] <- sum(UV >= Li2[i] & UV <= Ls2[i])
  } else {
    ni2[i] <- sum(UV >= Li2[i] & UV < Ls2[i])
  }
}
hi2 <- (ni2 / sum(ni2)) * 100

# Acumuladas
Ni_asc2 <- cumsum(ni2)
Hi_asc2 <- cumsum(hi2)
Ni_dsc2 <- rev(cumsum(rev(ni2)))
Hi_dsc2 <- rev(cumsum(rev(hi2)))


TDF_UV <- data.frame(
  Lim_inf = round(Li2,2),
  Lim_sup = round(Ls2,2),
  MC = round(MC2,2),
  ni = ni2,
  hi = round(hi2,2),
  Ni_asc = Ni_asc2,
  Hi_asc = round(Hi_asc2,2),
  Ni_dsc = Ni_dsc2,
  Hi_dsc = round(Hi_dsc2,2)
)

# Convertir todo a texto para la presentación final
TDF_UV[] <- lapply(TDF_UV, as.character)

# Fila TOTAL
TDF_Total <- data.frame(
  Lim_inf = "TOTAL",
  Lim_sup = "",
  MC = "",
  ni = as.character(sum(ni2)),
  hi = as.character(round(sum(hi2),2)),
  Ni_asc = "",
  Hi_asc = "",
  Ni_dsc = "",
  Hi_dsc = "",
  stringsAsFactors = FALSE
)

# Agregar fila total
TDF_UV <- rbind(TDF_UV, TDF_Total)

# Renombrar columnas
colnames(TDF_UV) <- c("Lim. Inf.", "Lim. Sup.", "MC", "ni", "hi (%)", "Ni Asc", "Hi Asc", "Ni Dsc", "Hi Dsc")

# Mostrar tabla con kable
kable(
  TDF_UV,
  align = "c",
  caption = "Tabla N°4: Distribución de frecuencias relativa del índice UV de los registros meteorológicos mundiales en período 2024–2026"
) |>
  kable_styling(
    full_width = TRUE,
    position = "center",
    bootstrap_options = c("striped", "hover", "condensed", "responsive")
  ) |>
  row_spec(0, bold = TRUE, color = "white", background = "#2C3E50") |>
  row_spec(nrow(TDF_UV), bold = TRUE, background = "#EAEDED") |>
  footnote(
    general = "Elaborado por Grupo 2.\nFuente: Global Weather Repository.",
    general_title = "Nota: ",
    footnote_as_chunk = TRUE,
    title_format = c("italic","bold")
  )
Tabla N°4: Distribución de frecuencias relativa del índice UV de los registros meteorológicos mundiales en período 2024–2026
Lim. Inf. Lim. Sup. MC ni hi (%) Ni Asc Hi Asc Ni Dsc Hi Dsc
0 2 1 72442 51.12 72442 51.12 141703 100
2 4 3 16133 11.39 88575 62.51 69261 48.88
4 6 5 15137 10.68 103712 73.19 53128 37.49
6 8 7 18611 13.13 122323 86.32 37991 26.81
8 10 9 11392 8.04 133715 94.36 19380 13.68
10 12 11 5301 3.74 139016 98.1 7988 5.64
12 14 13 2043 1.44 141059 99.55 2687 1.9
14 16 15 635 0.45 141694 99.99 644 0.45
16 18 17 9 0.01 141703 100 9 0.01
TOTAL 141703 100
Nota: Elaborado por Grupo 2.
Fuente: Global Weather Repository.

4. Gráfica de distribución de frecuencia

breaks_hi <- c(Li2, max(Ls2))

# 2. Generar el histograma en escala de frecuencia relativa pura
hist(
  UV,
  breaks = breaks_hi,
  probability = TRUE,                  
  col = "skyblue",                     
  border = "black",
  xlim = c(min(breaks_hi), max(breaks_hi)),
  main = "Gráfico N°5: Histograma Local de Frecuencia Relativa del Índice UV\n(Período 2024 al 2026)",
  xlab = "Índice UV",
  ylab = "Frecuencia Relativa",
  xaxt = "n"                           
)

# 3. Crear marcas del eje X exactamente en tus límites de clase ajustados [0, 2, 4, 6...]
axis(
  1, 
  at = breaks_hi, 
  labels = breaks_hi
)

# 4. Agregar rejilla sutil de fondo
grid()

5. Conjetura

# Se conjetura que el Índice UV sigue un modelo de probabilidad exponencial, 
# ya que la variable en su histograma muestra que la mayor parte de los datos 
# está fuertemente concentrada en el extremo izquierdo (valores bajos de radiación) 
# y la densidad de probabilidad disminuye rápidamente conforme aumentan dichos valores.

5.1. Cálculo de parámetros distribución exponencial

# Media de la variable original (UV)
media <- mean(UV)
print(paste("Media:", round(media, 4)))
## [1] "Media: 3.2724"
# Parámetro Lambda (Tasa de decaimiento)
lambda <- 1 / media
print(paste("Lambda:", round(lambda, 4)))
## [1] "Lambda: 0.3056"

5.2. Histograma de Densidad de Probabilidad con Modelo Exponencial

# Usamos los límites numéricos puros que creamos en el paso 3.5
breaks_exponencial <- c(Li2, max(Ls2))

hist(
  UV,
  breaks = breaks_exponencial,
  probability = TRUE,                  
  col = "skyblue",                     
  border = "black",
  xlim = c(min(breaks_exponencial), max(breaks_exponencial)),
  main = "Gráfico N°5: Comparación del Modelo Exponencial con la Realidad\ndel Índice UV (Período 2024 al 2026)",
  xlab = "UV (%)",
  ylab = "Densidad de probabilidad",
  xaxt = "n"
)

# Crear marcas del eje X exactamente en los límites de clase
axis(1, at = breaks_exponencial, labels = breaks_exponencial)

# Calcular el parámetro lambda con los datos de la variable UV
lambda <- 1 / mean(UV)

# Superponer la curva exponencial teórica en color rojo
curve(
  dexp(x, rate = lambda),
  from = min(breaks_exponencial),
  to = max(breaks_exponencial),
  add = TRUE,
  col = "red",
  lwd = 3
)

grid()

6. Test de bondad

# Filtrar y construir la tabla truncada numéricamente de 0 a 8 usando tus datos reales
TDF_truncada <- data.frame(
  LimInf = c(0, 2, 4, 6),
  LimSup = c(2, 4, 6, 8),
  ni     = ni2[1:4] # Toma los primeros 4 intervalos correspondientes a [0-2], [2-4], [4-6], [6-8]
)

fo <- TDF_truncada$ni
n  <- sum(fo)

# Recalculamos lambda para este rango controlado de la variable UV
lambda <- 1 / mean(UV[UV <= 8])

fe <- numeric(length(fo))
for(i in 1:length(fo)){
  fe[i] <- n * (pexp(TDF_truncada$LimSup[i], rate = lambda) - 
                  pexp(TDF_truncada$LimInf[i], rate = lambda))
}


# CORRELACIÓN DE PEARSON (%) 

Correlacion <- cor(fo, fe) * 100
print(paste("Correlación de Pearson:", round(Correlacion, 2), "%"))
## [1] "Correlación de Pearson: 92.1 %"
# TEST DE CHI-CUADRADO

fe_frac <- fe / n
fo_frac <- fo / n
x2 <- sum((fo_frac - fe_frac)^2 / fe_frac)

# Grados de libertad: k (4 intervalos) - 1 - 1
gl <- length(fo_frac) - 2 

umbral_aceptacion <- qchisq(0.95, df = gl)
acepta_modelo <- x2 < umbral_aceptacion

# Impresión de resultados en consola
print(paste("Estadístico X2:", round(x2, 4)))
## [1] "Estadístico X2: 0.2905"
print(paste("Grados de libertad (gl):", gl)) 
## [1] "Grados de libertad (gl): 2"
print(paste("Umbral de aceptación:", round(umbral_aceptacion, 4)))
## [1] "Umbral de aceptación: 5.9915"
print(paste("¿El modelo exponencial es aceptado?:", acepta_modelo))
## [1] "¿El modelo exponencial es aceptado?: TRUE"

7. Cálculo de probabilidades (modelo exponencial)

# “¿Cuál es la probabilidad de que el Índice UV registrado se encuentre en un nivel moderado a alto, entre 4 y 7 unidades?”
prob1 <- pexp(7, rate = lambda) - pexp(4, rate = lambda)
print(paste("Probabilidad de Índice UV entre 4 y 7:", round(prob1 * 100, 2), "%"))
## [1] "Probabilidad de Índice UV entre 4 y 7: 13.62 %"
# “¿Cuál es la probabilidad de que el Índice UV registrado sea extremadamente alto, es decir, mayor a 10 unidades?”
prob2 <- 1 - pexp(10, rate = lambda)
print(paste("Probabilidad de Índice UV mayor a 10 (Extremo):", round(prob2 * 100, 2), "%"))
## [1] "Probabilidad de Índice UV mayor a 10 (Extremo): 1.61 %"

8. Demostración cálculo de probabilidad

x <- seq(0, 18, by=0.001)
y <- dexp(x, rate=lambda)
ylim_max <- max(y) * 1.1

#Graficar curva principal del Modelo Exponencial
  plot(
  x, y, 
  type="l", 
  col="orange", 
  lwd=2, 
  xlim=c(0, 18), 
  ylim=c(0, ylim_max),
  main="Gráfica N°6: Demostración del Cálculo de Probabilidad", 
  ylab="Densidad de probabilidad", 
  xlab="Radiación Ultravioleta (UV)", 
  xaxt="n"
)

# --- Sombreado para el área entre 4 y 7 unidades ---
x_section <- seq(4, 7, by=0.001)
y_section <- dexp(x_section, rate=lambda)

# Sombrear el área con polígono (Verde semitransparente)
polygon(
  c(x_section, rev(x_section)), 
  c(y_section, rep(0, length(y_section))),
  col=rgb(0, 1, 0, 0.4), 
  border=NA
) 

# Dibujar línea verde sobre el área de interés
lines(x_section, y_section, col="green", lwd=2)

# Leyenda del gráfico
legend(
  "topright", 
  legend=c("Modelo Exponencial", "Probabilidad (4 <= UV <= 7)"), 
  col=c("orange","green"), 
  lwd=2, 
  lty=c(1,1),
  bty="n"
)

# Eje X de 2 en 2 para mantener la concordancia con tu histograma
axis(1, at=seq(0, 18, by=2))

grid()

9. Intervalo de confianza

library(gt)
library(dplyr)

# Parámetros de tu variable real (Radiación Ultravioleta - UV)
media <- mean(UV)
sigma <- sd(UV)
n     <- length(UV)

# Cálculo del error estándar (Aproximación z = 2 para el 95.44% o z = 1.96 para el 95%)
error <- 2 * (sigma / sqrt(n))

# Límites del intervalo de confianza
limite_inferior <- round(media - error, 2)
limite_superior <- round(media + error, 2)

# Crear el texto del intervalo matemático 
texto_intervalo <- paste0("P [", limite_inferior, " < \u00b5 < ", limite_superior, "] = 95%")

# Construcción de la tabla formal con gt
tabla_intervalo <- data.frame(Intervalo = texto_intervalo)

tabla_intervalo %>%
  gt() %>%
  tab_header(
    title = md("Tabla Nro. 5"), 
    subtitle = md("*Intervalo de confianza del índice de radiación ultravioleta*")
  ) %>%
  tab_source_note(
    source_note = md("Autor: Grupo 2")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    table.border.top.style = "solid",
    table.border.bottom.style = "solid",
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    row.striping.include_table_body = TRUE,
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black"
  )
Tabla Nro. 5
Intervalo de confianza del índice de radiación ultravioleta
Intervalo
P [3.25 < µ < 3.29] = 95%
Autor: Grupo 2

10. Conclusión

La variable de índice de radiación ultravioleta se explica con un modelo exponencial con parámetro λ = 0.3058, y podemos afirmar con un 95% de confianza que la media aritmética de esta variable se encuentra entre 3.25 y 3.29 unidades, con una desviación estándar de 3.54%.