0. Librerías

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

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. Tabla de distribución de Frecuencia

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

# Crear los limítes Numéricos 

breaks_seq <- seq(floor(valor_min/2)*2, ceiling(valor_max/2)*2, by = 2)
Li2 <- head(breaks_seq, -1)
Ls2 <- tail(breaks_seq, -1)
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))

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°1: 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°1: 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 Relativa

# Usamos directamente la secuencia completa de cortes (0, 2, 4, 6, ..., 18)
breaks_hi <- breaks_seq

# 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"                            
)

# Marcas exactas en el eje X (0, 2, 4, 6, 8, 10, 12, 14, 16, 18)
axis(
  1, 
  at = breaks_hi, 
  labels = breaks_hi
)

# Rejilla 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.

6 . Cálculo de parámetros

# calculamos el valor medio (UV)

media <- mean(UV)
print(paste("Media:", round(media, 4)))
## [1] "Media: 3.2724"
# Parámetro Lambda (el inverso de la media)
lambda <- 1 / media
print(paste("Lambda:", round(lambda, 4)))
## [1] "Lambda: 0.3056"
# desviación estándar

desviacion_estandar <- sd(UV)
print(desviacion_estandar)
## [1] 3.537579

7 . Sobreposición de la realidad con el modelo

# Usamos los límites numéricos puros que creamos en el paso 3.5
breaks_exponencial <- breaks_seq

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()

8. Test de bondad

8.1 . Test de Pearson

Nos dice qué tan parecidas son las formas de la curva real (datos) y la curva teórica (modelo normal).

fo <- ni2

n  <- sum(fo)

# Cálculo de frecuencias esperadas usando la tasa lambda global

fe <- numeric(length(fo))

for(i in 1:length(fo)){

  fe[i] <- n * (pexp(Ls2[i], rate = lambda) - pexp(Li2[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: 93.05 %"

##8.2 .Test de Chi-cuadrado

fe <- fe / n

fo <- fo / n

x2 <- sum((fo - fe)^2 / fe)

# Grados de libertad: k (intervalos totales) - 1 (suma) - 1 (estimación lambda)

gl <- length(fo) - 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.1893"
print(paste("Grados de libertad (gl):", gl)) 
## [1] "Grados de libertad (gl): 7"
print(paste("Umbral de aceptación:", round(umbral_aceptacion, 4)))
## [1] "Umbral de aceptación: 14.0671"
print(paste("¿El modelo exponencial es aceptado?:", acepta_modelo))
## [1] "¿El modelo exponencial es aceptado?: TRUE"

9 . Cálculo de probabilidades

##9.1.¿Pregunta de procentaje y cantidad ?

# “¿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: 17.68 %"
# “¿Cuál es la cantidad de días en 2027 que tendrá un índice UV mayor a 10?”

prob_UV_mayor_10 <- 1 - pexp(10, rate = lambda)
dias_2027 <- round(prob_UV_mayor_10 * 365, 0)

print(paste("Cantidad esperada de días en 2027 con UV > 10:", dias_2027, "días"))
## [1] "Cantidad esperada de días en 2027 con UV > 10: 17 días"

9.2. Demostración de probabilidad Gráfica

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()

10 . Intervalo de confianza

# Parámetros de tu variable real (Radiación Ultravioleta - UV)
media <- mean(UV)   # Media muestral (3.2724)
sigma <- sd(UV)     # Desviación estándar muestral (3.54)
n     <- length(UV) # Tamaño total de la muestra (141,703)
z     <- 2          # Valor aproximado  para 95%)
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\nFuente: Global Weather Repository.")
  ) %>%
  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 Fuente: Global Weather Repository.

11. Conclusión

La variable de índice de radiación ultravioleta se explica con un modelo exponencial con parámetro λ = 0.3056, 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, este resultado es favorable ya que el riesgo es moderado.