0. Librerías

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

1. Carga de datos

variables <- read.csv("C:/Users/WAN/Downloads/GlobalWeatherRepository.csv",
                      header = TRUE,
                      sep = ",",
                      dec = ".",
                      na.strings = "-")

2. Selección y depuración de la variable aleatoria

# Filtramos valores normales de presión atmosférica (entre 900 y 1100 mbar) para eliminar errores
Presion_mbar <- variables$pressure_mb
Presion_mbar <- Presion_mbar[Presion_mbar >= 900 & Presion_mbar <= 1100]
Presion_mbar <- na.omit(Presion_mbar)

n <- length(Presion_mbar)

3. Tabla de distribución de Frecuencia

# 3. Tabla de Distribución de Frecuencias (Versión Simplificada)

# 3.1. Rango y definición de intervalos simplificados (k = 9 clases) enteros
valor_min <- floor(min(Presion_mbar, na.rm = TRUE)) # Redondea hacia abajo al entero más cercano
valor_max <- ceiling(max(Presion_mbar, na.rm = TRUE)) # Redondea hacia arriba al entero más cercano
R <- valor_max - valor_min

k_tabla2 <- 9
A2 <- R / k_tabla2

# Límites de clase y Marcas de clase (Redondeados a 0 decimales)
Li2 <- seq(from = valor_min, to = valor_max - A2, by = A2)
Ls2 <- c(seq(from = valor_min + A2, to = valor_max - A2, by = A2), valor_max)

Li2 <- round(Li2, 0)
Ls2 <- round(Ls2, 0)
MC2 <- round((Li2 + Ls2) / 2, 0)

# 3.2. Conteo de frecuencias absolutas
ni2 <- numeric(length(Li2))
for(i in 1:length(Li2)){
  if(i < length(Li2)){
    ni2[i] <- sum(Presion_mbar >= Li2[i] & Presion_mbar < Ls2[i])
  } else {
    ni2[i] <- sum(Presion_mbar >= Li2[i] & Presion_mbar <= Ls2[i])
  }
}

# 3.3. Frecuencias relativas y acumuladas
hi2 <- (ni2 / n) * 100
Ni2_asc <- cumsum(ni2)
Hi2_asc <- cumsum(hi2)
Ni2_desc <- rev(cumsum(rev(ni2)))
Hi2_desc <- rev(cumsum(rev(hi2)))

# 3.4. Creación del Data Frame simplificado (Sin decimales en límites y marcas)
TDF_Presion_mbar <- data.frame(
  Lim_inf = round(Li2, 0),
  Lim_sup = round(Ls2, 0),
  MC = round(MC2, 0),
  ni = ni2,
  hi = round(hi2, 2), # El porcentaje conserva decimales si lo deseas para mayor precisión
  Ni_asc = Ni2_asc,
  Hi_asc = round(Hi2_asc, 2),
  Ni_dsc = Ni2_desc,
  Hi_dsc = round(Hi2_desc, 2)
)

# 3.5. Mostrar tabla con kable y kableExtra (Función corregida: add_footnote)
kable(
  TDF_Presion_mbar,
  align = "c",
  caption = "Tabla N° 1: Distribución de frecuencias agrupadas de la Presión en mbar de los registros meteorológicos mundiales, 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_Presion_mbar),
    bold = TRUE,
    background = "#EAEDED"
  ) |>
  add_footnote(
    label = "Elaborado por Grupo 2. Fuente: Global Weather Repository.",
    notation = "none"
  )
Tabla N° 1: Distribución de frecuencias agrupadas de la Presión en mbar de los registros meteorológicos mundiales, período 2024–2026
Lim_inf Lim_sup MC ni hi Ni_asc Hi_asc Ni_dsc Hi_dsc
947 962 954 1 0.00 1 0.00 141701 100.00
962 977 970 40 0.03 41 0.03 141700 100.00
977 991 984 407 0.29 448 0.32 141660 99.97
991 1006 998 10483 7.40 10931 7.71 141253 99.68
1006 1021 1014 108077 76.27 119008 83.99 130770 92.29
1021 1036 1028 22226 15.69 141234 99.67 22693 16.01
1036 1050 1043 457 0.32 141691 99.99 467 0.33
1050 1065 1058 9 0.01 141700 100.00 10 0.01
1065 1080 1072 1 0.00 141701 100.00 1 0.00
Elaborado por Grupo 2. Fuente: Global Weather Repository.

4. Gráfica de Distribución de Frecuencia Relativa

bp <- barplot(hi2,
              space = 0,
              names.arg = FALSE,
              xaxt = "n",
              yaxt = "n",
              main = "Gráfica N°1. Distribución de frecuencias relativas de la Presión mbar (2024–2026)",
              xlab = " ()",
              ylab = "Porcentaje (%)",
              col = "skyblue",
              border = "black",
              ylim = c(0, max(hi2) * 1.25),
              cex.main = 0.9)

# Etiquetas de Eje X e Y
Etiquetas <- paste0("[", round(Li2, 0), "-", round(Ls2, 0), ")")
Etiquetas[length(Etiquetas)] <- paste0("[", round(Li2[length(Li2)], 0), "-", round(Ls2[length(Ls2)], 0), "]")

axis(1, at = bp, labels = Etiquetas, las = 2, cex.axis = 0.8)
axis(2, at = seq(0, ceiling(max(hi2)), by = 5), las = 1)
grid()

5. Conjetura del modelo

# H0: La Presión mbar sigue una distribución Normal N(mu, sigma)
# H1: La Presión mbar no sigue una distribución Normal

6. Parámetros

# Definición de límites del rango según los datos reales de presión
valor_min_real <- min(Presion_mbar, na.rm = TRUE)
valor_max_real <- max(Presion_mbar, na.rm = TRUE)

# Creamos 5 intervalos proporcionales basados en tu rango real
cortes_parametros <- seq(valor_min_real, valor_max_real, length.out = 6)
Li <- cortes_parametros[1:5]
Ls <- cortes_parametros[2:6]

# Marcas de clase (x_i)
x_i <- (Li + Ls) / 2

# Frecuencias absolutas (ni) utilizando el rango real de presión
Presion_mbar_filtrado <- Presion_mbar[Presion_mbar >= valor_min_real & Presion_mbar <= valor_max_real]
Presion_mbar_filtrado <- Presion_mbar_filtrado[!is.na(Presion_mbar_filtrado)]

ni <- numeric(length(Li))
for(i in 1:length(Li)){
  if(i < length(Li)){
    ni[i] <- sum(Presion_mbar_filtrado >= Li[i] & Presion_mbar_filtrado < Ls[i])
  } else {
    ni[i] <- sum(Presion_mbar_filtrado >= Li[i] & Presion_mbar_filtrado <= Ls[i])
  }
}

# Suma total de frecuencias absolutas
N <- sum(ni)

# Media y desviación estándar ponderadas
mu <- sum(x_i * ni) / N
sigma <- sqrt(sum(ni * (x_i - mu)^2) / (N - 1))

cat("Suma total de frecuencias (N):", N, "\n")
## Suma total de frecuencias (N): 141701
cat("Media ponderada (mu):", round(mu, 4), "\n")
## Media ponderada (mu): 1014.013
cat("Desviación estándar ponderada (sigma):", round(sigma, 4), "\n")
## Desviación estándar ponderada (sigma): 7.2195

7. Sobreposición de la realidad con el modelo

# 7. Sobreposición de la realidad con el modelo
# Usamos exactamente los mismos límites enteros de la tabla simplificada
cortes_tabla <- c(Li2, max(Ls2))

# Ajustamos el filtro de la sección 6 con los límites exactos de la tabla
Presion_mbar_filtrado <- Presion_mbar[Presion_mbar >= min(Li2) & Presion_mbar <= max(Ls2)]
Presion_mbar_filtrado <- Presion_mbar_filtrado[!is.na(Presion_mbar_filtrado)]

# Graficar histograma basado estrictamente en las clases de la tabla
Histograma_Presion_mbar <- hist(Presion_mbar_filtrado,
                           breaks = cortes_tabla,
                           freq = FALSE,          
                           main = "Gráfica Nº2: Comparación de la realidad con el modelo normal\nde Presión Atmosférica Mundial", 
                           xlab = "Presión Atmosférica (mbar)",
                           ylab = "Densidad de probabilidad",
                           col = "#AEC6CF", # Color azul pastel estético
                           border = "white", # Bordes blancos para definir mejor las barras
                           ylim = c(0, dnorm(mu, mu, sigma) * 1.2),
                           xaxt = "n",
                           las = 1) 

# Forzar a que el eje X muestre exactamente los cortes enteros de la tabla
axis(1, at = cortes_tabla, labels = cortes_tabla, las = 2, cex.axis = 0.8)

# Curva normal teórica sobrepuesta con alta resolución
x_curve <- seq(min(Presion_mbar_filtrado), max(Presion_mbar_filtrado), length.out = 1000)
lines(x_curve, dnorm(x_curve, mean = mu, sd = sigma), col = "#2C3E50", lwd = 3)

# Agregar cuadrícula sutil de fondo
grid(nx = NA, ny = NULL, col = "gray", lty = "dotted")

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 <- as.numeric(table(cut(Presion_mbar_filtrado, breaks = cortes_tabla, include.lowest = TRUE)))
n_filt <- length(Presion_mbar_filtrado)

mu_real <- mean(Presion_mbar_filtrado, na.rm = TRUE)
sigma_real <- sd(Presion_mbar_filtrado, na.rm = TRUE)

p_teorica <- diff(pnorm(cortes_tabla, mean = mu_real, sd = sigma_real))
Fe <- p_teorica * n_filt

Correlacion <- cor(Fo, Fe) * 100
cat("Correlación Pearson Fo vs Fe:", round(Correlacion, 2), "%\n")
## Correlación Pearson Fo vs Fe: 99.79 %

8.2. Test de Chi-cuadrado

## 8.2. Test de Chi-cuadrado minimizado (Suma de diferencias al cuadrado de fracciones 0 a 1)
Fo_fraccion <- Fo / n_filt
Fe_fraccion <- p_teorica 

# Modificación: Eliminamos la división por Fe_fraccion para evitar que el valor explote en las colas
x2 <- sum((Fo_fraccion - Fe_fraccion)^2)

# Configuración de grados de libertad de tu plantilla
grados_libertad <- length(Fo) - 1
umbral_aceptacion <- qchisq(0.95, df = grados_libertad)

cat("Estadístico X2 (Suma de diferencias al cuadrado 0 a 1):", format(round(x2, 7), nsmall = 7), "\n")
## Estadístico X2 (Suma de diferencias al cuadrado 0 a 1): 0.0037862
cat("Valor crítico (Umbral de la Tabla):", round(umbral_aceptacion, 4), "\n")
## Valor crítico (Umbral de la Tabla): 15.5073
cat("¿Acepta H0 (X2 < Umbral)?:", x2 < umbral_aceptacion, "\n")
## ¿Acepta H0 (X2 < Umbral)?: TRUE

9. Cálculo de probabilidades

9.1. Pregunta de Porcentaje

# ¿Cuál es la probabilidad de que la presión atmosférica esté comprendida entre 1005 mbar y 1020 mbar?
lim_inf_prob <- 1005
lim_sup_prob <- 1020

prob_1005_1020 <- (pnorm(lim_sup_prob, mu, sigma) - pnorm(lim_inf_prob, mu, sigma)) * 100

cat("Probabilidad (1005 mbar a 1020 mbar):", round(prob_1005_1020, 2), "%\n")
## Probabilidad (1005 mbar a 1020 mbar): 69.06 %
# Demostración gráfica para el intervalo [1005 mbar, 1020 mbar]
x_graf <- seq(min(Presion_mbar_filtrado), max(Presion_mbar_filtrado), by = 0.01)

plot(x_graf, dnorm(x_graf, mu, sigma),
     type = "l",
     col = "skyblue3",
     lwd = 2,
     main = "Gráfica N° 3: Cálculo de probabilidades (1005 mbar a 1020 mbar)",
     ylab = "Densidad de probabilidad",
     xlab = "Presión Atmosférica (mbar)")

# Sombrear la región de integración [1005 mbar, 1020 mbar]
x_sec <- seq(lim_inf_prob, lim_sup_prob, by = 0.01)
y_sec <- dnorm(x_sec, mu, sigma)

lines(x_sec, y_sec, col = "red", lwd = 2)
polygon(c(lim_inf_prob, x_sec, lim_sup_prob), c(0, y_sec, 0), col = rgb(1, 0, 0, 0.2), border = NA)

9.2. Pregunta de Cantidad Esperada

# ¿Cuántos registros meteorológicos se espera que tengan una presión superior a 1025 mbar?
lim_superior_alta <- 1025

# Calcular la probabilidad teórica P(X > 1025)
prob_alta_presion <- pnorm(lim_superior_alta, mu, sigma, lower.tail = FALSE)

# Multiplicar por el número total de registros filtrados (n_filt) para obtener la cantidad esperada
cantidad_esperada <- prob_alta_presion * n_filt

cat("Probabilidad de presión > 1025 mbar:", round(prob_alta_presion * 100, 2), "%\n")
## Probabilidad de presión > 1025 mbar: 6.4 %
cat("Cantidad esperada de registros meteorológicos:", round(cantidad_esperada, 0), "de un total de", n_filt, "\n")
## Cantidad esperada de registros meteorológicos: 9073 de un total de 141701

10. Intervalos de confianza

media_pob <- mean(Presion_mbar)
sigma_pob <- sd(Presion_mbar)
n_pob <- length(Presion_mbar)

error_estandar <- qnorm(0.975) * (sigma_pob / sqrt(n_pob))

lim_inf <- round(media_pob - error_estandar, 2)
lim_sup <- round(media_pob + error_estandar, 2)

# Tabla GT para Intervalo de Confianza
tabla_ic <- data.frame(
  Indicador = " Presión mbar ()",
  Nivel_Confianza = "95%",
  Intervalo = paste0("P [", lim_inf, " < µ < ", lim_sup, "] = 0.95"),
  Desviacion_Estandar = round(sigma_pob, 2)
)

tabla_ic %>%
  gt() %>%
  tab_header(
    title = md("*Tabla N° 2*"),
    subtitle = md("Intervalo de confianza para la media de la  Presión mbar (2024–2026)")
  ) %>%
  tab_source_note(
    source_note = md("Autor: Grupo 2 <br> Fuente: Global Weather Repository.")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    row.striping.include_table_body = TRUE
  )
Tabla N° 2
Intervalo de confianza para la media de la Presión mbar (2024–2026)
Indicador Nivel_Confianza Intervalo Desviacion_Estandar
Presión mbar () 95% P [1013.97 < µ < 1014.04] = 0.95 6.95
Autor: Grupo 2
Fuente: Global Weather Repository.

11. Conclusión

La variable aleatoria ‘Presion_mbar’ de los registros meteorológicos mundiales se explica adecuadamente mediante un modelo de distribución normal con parámetros de una media aritmética que está entre 1013.97 < µ < 1014.04 y una desviación estándar de 6.95, lo cual resulta beneficioso tanto para la salud como para el medio ambiente. Esta notable estabilidad en torno a la presión estándar ideal a nivel del mar y su baja variabilidad demuestran que las fluctuaciones extremas son raras a escala global; esto protege la salud humana, mientras que ambientalmente asegura un equilibrio dinámico que frena la formación constante de fenómenos climáticos severos y destructivos.