0. Librerias

library(knitr)
library(kableExtra)
library(e1071)

1. Leer Datos

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

2. Extraer y Depuración de la Variable

Pmbar_original <- na.omit(variables$pressure_mb)

# Filtro estadístico/físico: Mantener solo valores realistas, ya que al existir outliers no se visualiza de buena manera la gran mayoría de datos.
Pmbar <- Pmbar_original[Pmbar_original >= 800 & Pmbar_original <= 1100]

# Total de datos limpios
n_total <- length(Pmbar)

3. Frecuencias

3.1 Max y Min

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

rango <- valor_max - valor_min

3.2. Regla de Sturges

K_sturges <- floor(1 + 3.322 * log10(n_total))

cat("Número de clases:", K_sturges, "\n")
## Número de clases: 18
A_sturges <- rango / K_sturges

cat("Amplitud Sturges:", A_sturges, "\n")
## Amplitud Sturges: 7.388889

3.3. Intervalos

Li1 <- seq( valor_min,
            valor_max - A_sturges,
            by = A_sturges
)

Ls1 <- Li1 + A_sturges

3.4. Bucle para las columnas de la tabla

ni1 <- numeric(length(Li1))

for(i in 1:length(Li1)){
  
  if(i == length(Li1)){
    
    ni1[i] <- sum(
      Pmbar >= Li1[i] &
        Pmbar <= Ls1[i]
    )
    
  } else {
    
    ni1[i] <- sum(
      Pmbar >= Li1[i] &
        Pmbar < Ls1[i]
    )
  }
}

# Frecuencia relativa
hi1 <- (ni1 / sum(ni1)) * 100

# Acumuladas
Ni_asc1 <- cumsum(ni1)
Hi_asc1 <- cumsum(hi1)

Ni_dsc1 <- rev(cumsum(rev(ni1)))
Hi_dsc1 <- rev(cumsum(rev(hi1)))

# Marca de clase
MC1 <- (Li1 + Ls1)/2

3.5. Amplitud para tabla ajustada

amplitud <- 14

# Intervalos
Li2 <- seq(
  floor(valor_min/14)*14,
  ceiling(valor_max/14)*14 - 14,
  by = 14
)

Ls2 <- Li2 + 14

#Frecuencias

ni2 <- numeric(length(Li2))

for(i in 1:length(Li2)){
  
  if(i == length(Li2)){
    
    ni2[i] <- sum(
      Pmbar >= Li2[i] &
        Pmbar <= Ls2[i]
    )
    
  } else {
    
    ni2[i] <- sum(
      Pmbar >= Li2[i] &
        Pmbar < Ls2[i]
    )
  }
}

# Frecuencia relativa
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)))

# Marca de clase
MC2 <- (Li2 + Ls2)/2

4. Tabla de Distribución de Frecuencias

4.1. Tabla según Sturges

# Convertir a caracteres para poder mezclar números y texto

Tabla_Sturges <- data.frame(
  
  Lim_inf = round(Li1,2),
  
  Lim_sup = round(Ls1,2),
  
  MC = round(MC1,2),
  
  ni = ni1,
  
  hi = round(hi1,2),
  
  Ni_asc = Ni_asc1,
  
  Hi_asc = round(Hi_asc1,2),
  
  Ni_dsc = Ni_dsc1,
  
  Hi_dsc = round(Hi_dsc1,2)
  
)

Tabla_Sturges2 <- Tabla_Sturges
Tabla_Sturges2[] <- lapply(Tabla_Sturges2, as.character)

# Fila de totales

fila_total <- data.frame(
  Lim_inf = "TOTAL",
  Lim_sup = "",
  MC = "",
  ni = as.character(sum(ni1)),
  hi = as.character(round(sum(hi1), 2)),
  Ni_asc = "",
  Hi_asc = "",
  Ni_dsc = "",
  Hi_dsc = ""
)

# Agregar fila

Tabla_Sturges2 <- rbind(Tabla_Sturges2, fila_total)


kable(
  Tabla_Sturges2,
  align = "c",
  caption = "Tabla N1: Distribución de frecuencias de Presión en milibareses de los 
  registros meteorológicos mundiales mediante la regla de Sturges, 
  período 2024–2026") |>
  
  kableExtra::kable_styling(
    full_width = TRUE,
    position = "center",
    bootstrap_options = c(
      "striped",
      "hover",
      "condensed",
      "responsive"
    )
  ) |>
  
  kableExtra::row_spec(
    0,
    bold = TRUE,
    color = "white",
    background = "#2C3E50"
  ) |>
  
  kableExtra::row_spec(
    nrow(Tabla_Sturges2),
    bold = TRUE,
    background = "#EAEDED"
  )|>
  footnote(
    general = "Elaborado por Grupo 2. Debido a la complejidad de la tabla se aplica el criterio de simplificar la tabla anterior para una mejor visualización y posterior análisis para esta variable. 
    Fuente: Global Weather Repository.",
    general_title = "Nota: ",
    footnote_as_chunk = TRUE,
    title_format = c("italic","bold")
  )
Tabla N1: Distribución de frecuencias de Presión en milibareses de los registros meteorológicos mundiales mediante la regla de Sturges, período 2024–2026
Lim_inf Lim_sup MC ni hi Ni_asc Hi_asc Ni_dsc Hi_dsc
947 954.39 950.69 1 0 1 0 141701 100
954.39 961.78 958.08 0 0 1 0 141700 100
961.78 969.17 965.47 10 0.01 11 0.01 141700 100
969.17 976.56 972.86 30 0.02 41 0.03 141690 99.99
976.56 983.94 980.25 97 0.07 138 0.1 141660 99.97
983.94 991.33 987.64 397 0.28 535 0.38 141563 99.9
991.33 998.72 995.03 1979 1.4 2514 1.77 141166 99.62
998.72 1006.11 1002.42 11602 8.19 14116 9.96 139187 98.23
1006.11 1013.5 1009.81 57037 40.25 71153 50.21 127585 90.04
1013.5 1020.89 1017.19 47855 33.77 119008 83.99 70548 49.79
1020.89 1028.28 1024.58 18916 13.35 137924 97.33 22693 16.01
1028.28 1035.67 1031.97 3310 2.34 141234 99.67 3777 2.67
1035.67 1043.06 1039.36 416 0.29 141650 99.96 467 0.33
1043.06 1050.44 1046.75 44 0.03 141694 100 51 0.04
1050.44 1057.83 1054.14 6 0 141700 100 7 0
1057.83 1065.22 1061.53 0 0 141700 100 1 0
1065.22 1072.61 1068.92 0 0 141700 100 1 0
1072.61 1080 1076.31 1 0 141701 100 1 0
TOTAL 141701 100
Nota: Elaborado por Grupo 2. Debido a la complejidad de la tabla se aplica el criterio de simplificar la tabla anterior para una mejor visualización y posterior análisis para esta variable.
Fuente: Global Weather Repository.

4.2. Tabla ajustada

TDF_Pmbar <- 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
TDF_Pmbar[] <- lapply(TDF_Pmbar, 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_Pmbar <- rbind(TDF_Pmbar, TDF_Total)

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

# Mostrar tabla

kable(
  TDF_Pmbar,
  align = "c",
  caption = "Tabla N2: Distribución de frecuencias Presión en milibareses de los registros meteorológicos mundiales con amplitud 
  de clase de 15°, 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_Pmbar),
    bold = TRUE,
    background = "#EAEDED"
  ) |>
  
  footnote(
    general = "Elaborado por Grupo 2. 
    Fuente: Global Weather Repository.",
    general_title = "Nota: ",
    footnote_as_chunk = TRUE,
    title_format = c("italic","bold")
  )
Tabla N2: Distribución de frecuencias Presión en milibareses de los registros meteorológicos mundiales con amplitud de clase de 15°, período 2024–2026
Lim. Inf. Lim. Sup. MC ni hi (%) Ni Asc Hi Asc Ni Dsc Hi Dsc
938 952 945 1 0 1 0 141701 100
952 966 959 4 0 5 0 141700 100
966 980 973 66 0.05 71 0.05 141696 100
980 994 987 736 0.52 807 0.57 141630 99.95
994 1008 1001 17539 12.38 18346 12.95 140894 99.43
1008 1022 1015 104422 73.69 122768 86.64 123355 87.05
1022 1036 1029 18466 13.03 141234 99.67 18933 13.36
1036 1050 1043 457 0.32 141691 99.99 467 0.33
1050 1064 1057 9 0.01 141700 100 10 0.01
1064 1078 1071 0 0 141700 100 1 0
1078 1092 1085 1 0 141701 100 1 0
TOTAL 141701 100
Nota: Elaborado por Grupo 2.
Fuente: Global Weather Repository.

5. Gráficos de Distribución de Frecuencias

5.1. Histograma Original (ni)

hist(
  Pmbar,
  
  breaks = c(Li2, max(Ls2)),
  
  freq = TRUE,
  
  main = "Gráfico N°1. Distribución de frecuencias absolutas de 
  Presión en milibareses de los registros meteorológicos mundiales agrupados
  en intervalos de 15°, período 2024–2026",
  
  xlab = "Pmbar (%)",
  
  ylab = "Frecuencia absoluta (ni)",
  
  col = "lightgreen",
  
  border = "black",
  
  xaxt = "n"
)

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

grid()

5.2. Histograma con relación al todo (ni)

hist(
  Pmbar,
  
  breaks = c(Li2, max(Ls2)),
  
  ylim = c(0, n_total),
  
  main = "Gráfico N°2. Histograma y polígono de frecuencias 
  absolutas de Presión en milibareses de los registros meteorológicos mundiales, 
  período 2024–2026",
  
  xlab = "Pmbar",
  
  ylab = "Frecuencia",
  
  col = "lightgreen",
  
  border = "black"
)

grid()

5.3. Histograma original (hi)

# Crear una ventana vacía
plot(
  NA,
  xlim = c(min(Li2), max(Ls2)),
  ylim = c(0, max(hi2) * 1.1),
  main = "Gráfico N°3. Distribución de frecuencias relativas de Presión en milibareses
  de los registros meteorológicos mundiales agrupados en 
  intervalos de 15°, período 2024–2026",
  xlab = "Pmbar (%)",
  ylab = "Frecuencia Relativa (%)"
)

# Dibujar barras del histograma
rect(
  Li2,
  0,
  Ls2,
  hi2,
  col = "skyblue",
  border = "black"
)

grid()

5.4. Histograma con relacion a todo (hi)

plot(
  NA,
  xlim = c(min(Li2), max(Ls2)),
  ylim = c(0, 100),
  main = "Gráfico N°4. Histograma y polígono de frecuencias relativas 
  de Presión en milibareses de los registros meteorológicos mundiales, período 
  2024–2026",
  xlab = "Pmbar (%)",
  ylab = "Frecuencia Relativa (%)"
)

rect(
  Li2,
  0,
  Ls2,
  hi2,
  col = "lightgreen",
  border = "black"
)

grid()

5.5. Polígono de frecuencias (ni)

# Definir límites dinámicos basados en tus datos reales
min_x <- min(Li2)
max_x <- max(Ls2)

hist(
  Pmbar,
  breaks = c(Li2, max(Ls2)),
  freq = TRUE,
  xlim = c(min_x - 10, max_x + 10), 
  main = "Gráfico N°5. Polígono de frecuencias absolutas de Presión en milibareses de los registros meteorológicos mundiales, período 2024–2026",
  xlab = "Pmbar (mb)",              
  ylab = "Frecuencia Absoluta (ni)",
  col = "lightblue",
  border = "black",
  xaxt = "n"
)

# Colocar marcas en el eje X exactamente donde están tus intervalos reales
axis(
  1,
  at = seq(floor(min_x/20)*20, ceiling(max_x/20)*20, by = 20),
  labels = seq(floor(min_x/20)*20, ceiling(max_x/20)*20, by = 20)
)

# Coordenadas del polígono cerrado de forma correcta
# Para que cierre en el piso, usamos el límite inferior de la primera clase menos la mitad de la amplitud,
# y el límite superior de la última clase más la mitad de la amplitud.
ancho_clase <- Li2[2] - Li2[1]

x_pol <- c(MC2[1] - ancho_clase, MC2, MC2[length(MC2)] + ancho_clase)
y_pol <- c(0, ni2, 0)

# Dibujar polígono de frecuencias
lines(
  x_pol,
  y_pol,
  type = "o",   
  pch = 16,     
  lwd = 2,
  col = "red"
)

# Agregar cuadrícula
grid()

5.6. Polígono de frecuencias (hi)

plot(
  NA,
  xlim = c(min(Li2), max(Ls2)),
  ylim = c(0, max(hi2) * 1.2),
  main = "Gráfico N°6. Polígono de frecuencias relativas de Presión en milibareses de los registros meteorológicos mundiales, período 2024–2026",
  xlab = "Pmbar (%)",
  ylab = "Frecuencia Relativa (%)"
)

# Histograma
rect(
  Li2,
  0,
  Ls2,
  hi2,
  col = "lightgreen",
  border = "black"
)

# Coordenadas del polígono cerrado
x_pol <- c(MC2[1] - amplitud/2, MC2, MC2[length(MC2)] + amplitud/2)

y_pol <- c(0, hi2, 0)

lines(
  x_pol,
  y_pol,
  type = "o",
  pch = 16,
  lwd = 2,
  col = "red"
)

# Polígono de frecuencia
lines(
  MC2,
  hi2,
  type = "o",
  pch = 16,
  lwd = 2,
  col = "red"
)

grid()

5.7. Ojiva ascendente y descendente (ni)

plot(
  Ls2,
  Ni_asc2,
  
  type = "o",
  
  pch = 16,
  
  lwd = 2,
  
  col = "blue",
  
  ylim = c(0, max(Ni_asc2)),
  
  main = "Gráfico N°7: Ojivas ascendente y descendente de frecuencias absolutas acumuladas de Presión en milibareses de los registros meteorológicos mundiales, período 2024–2026",
  
  xlab = "Pmbar",
  
  ylab = "Frecuencia Acumulada (Ni)"
)

lines(
  Li2,
  Ni_dsc2,
  
  type = "o",
  
  pch = 17,
  
  lwd = 2,
  
  col = "red"
)

legend(
  "right",
  
  legend = c(
    "Ojiva Ascendente",
    "Ojiva Descendente"
  ),
  
  col = c(
    "blue",
    "red"
  ),
  
  pch = c(
    16,
    17
  ),
  
  lwd = 2,
  
  bty = "n"
)

grid()

5.8. Ojiva ascentende y descendente (hi)

plot(
  Ls2,
  Hi_asc2,
  type = "o",
  pch = 16,
  lwd = 2,
  col = "blue",
  ylim = c(0,100),
  main = "Gráfico N°8: Ojivas ascendente y descendente de frecuencias relativas acumuladas de Presión en milibareses de los registros meteorológicos mundiales, período 2024–2026",
  xlab = "Pmbar",
  ylab = "Frecuencia Acumulada (%)"
)

lines(
  Li2,
  Hi_dsc2,
  type = "o",
  pch = 17,
  lwd = 2,
  col = "red"
)

legend(
  "right",
  legend = c(
    "Ascendente",
    "Descendente"
  ),
  col = c("blue","red"),
  pch = c(16,17),
  lwd = 2,
  bty = "n"
)

grid()

5.9. Bloxplot

Q1 <- quantile(Pmbar, 0.25)

Q3 <- quantile(Pmbar, 0.75)

RIC <- Q3 - Q1

Lim_inf <- Q1 - 1.5 * RIC

Lim_sup <- Q3 + 1.5 * RIC
bp <- boxplot(
  Pmbar,
  horizontal = TRUE,
  outline = FALSE,
  main = "Gráfico N°9:Bloxplot de frecuencias de Presión en milibareses de los registros meteorológicos mundiales, período 2024–2026",
  xlab = "Pmbar",
  col = "lightblue"
)

atipicos <- Pmbar[
  Pmbar < Lim_inf |
    Pmbar > Lim_sup
]

points(
  atipicos,
  rep(1, length(atipicos)),
  col = "red",
  pch = 19,
  cex = 0.8
)

abline(v = Lim_inf, col = "blue", lwd = 2, lty = 2)
abline(v = Lim_sup, col = "blue", lwd = 2, lty = 2)

#Outliers

Lim_inf2 <- Q1 - 1.0 * RIC
Lim_sup2 <- Q3 + 1.0 * RIC

atipicos2 <- Pmbar[
  Pmbar < Lim_inf2 |
    Pmbar > Lim_sup2
]

length(atipicos2)
## [1] 11280
legend(
  "topright",
  legend = c(
    "Atípicos",
    "Límites de Tukey"
  ),
  col = c("red", "blue"),
  pch = c(19, NA),
  lty = c(NA, 2),
  lwd = c(NA, 2),
  bty = "n"
)

grid()

6. Indicadores Estadísticos

6.1. Tendencia central

media <- mean(Pmbar)

mediana <- median(Pmbar)

# Moda aproximada usando la clase modal

tabla_moda <- TDF_Pmbar[
  TDF_Pmbar$`Lim. Inf.` != "TOTAL",
]

ni_num <- as.numeric(tabla_moda$ni)

max_ni <- max(ni_num)

moda <- as.numeric(
  tabla_moda$MC[
    ni_num == max_ni
  ]
)

6.2. Dispersión

varianza <- var(Pmbar)

desv_est <- sd(Pmbar)

cv <- (desv_est / media) * 100

6.3. Forma

asimetria <- skewness(Pmbar)

curtosis <- kurtosis(Pmbar)

6.4. Valores atípicos

Q1 <- quantile(Pmbar, 0.25)

Q3 <- quantile(Pmbar, 0.75)

RIC <- Q3 - Q1

lim_inf <- Q1 - 1.5 * RIC

lim_sup <- Q3 + 1.5 * RIC

atipicos <- Pmbar[
  Pmbar < lim_inf |
    Pmbar > lim_sup
]

n_atipicos <- length(atipicos)

intervalo_atipicos <- paste0(
  "[",
  round(lim_inf,2),
  "; ",
  round(lim_sup,2),
  "]"
)

# Rango

rango_texto <- paste0(
  "[",
  round(min(Pmbar),2),
  "; ",
  round(max(Pmbar),2),
  "]"
)

6.5. Tabla de indicadores

tabla_indicadores <- data.frame(
  
  Variable = "Pmbar",
  
  Rango = rango_texto,
  
  Media = round(media,2),
  
  Mediana = round(mediana,2),
  
  Moda = round(moda,2),
  
  Varianza = round(varianza,2),
  
  Desv_Est = round(desv_est,2),
  
  CV = round(cv,2),
  
  Asimetria = round(asimetria,2),
  
  Curtosis = round(curtosis,2),
  
  Limite_Atipicos = intervalo_atipicos,
  
  N_Atipicos = n_atipicos
)

# Mostrar tabla

kable(
  tabla_indicadores,
  align = "c",
  caption = "Tabla N°3. Indicadores estadísticos descriptivos de la variable 
Presión en milibares en registros meteorológicos mundiales, período 2024–2026 en 
  registros meteorológicos mundiales, período 2024–2026"
) |>
  kable_styling(
    full_width = FALSE,
    position = "center",
    bootstrap_options = c(
      "striped",
      "hover",
      "condensed",
      "responsive"
    )
  ) |>
  row_spec(
    0,
    bold = TRUE,
    color = "white",
    background = "#2C3E50"
  )
Tabla N°3. Indicadores estadísticos descriptivos de la variable Presión en milibares en registros meteorológicos mundiales, período 2024–2026 en registros meteorológicos mundiales, período 2024–2026
Variable Rango Media Mediana Moda Varianza Desv_Est CV Asimetria Curtosis Limite_Atipicos N_Atipicos
Pmbar [947; 1080] 1014.01 1013 1015 48.27 6.95 0.69 0.05 1.91 [998; 1030] 4161

7. Conclusiones

El comportamiento de la variable presión en milibares (Pmbar) sigue la siguiente manera: fluctúa entre 947mbar y 1080mbar y sus valores giran en torno a la media aritmética de 1014.01mbar, con una desviación estándar de 6.95mbar, siendo un conjunto de datos muy homogéneo, ya que su coeficiente de variación es de tan solo 0.69%. El conjunto de valores presenta una distribución leptocúrtica de Curtosis = 1.91, lo que indica una mayor concentración de datos alrededor del centro en comparación con una distribución normal. Además, muestra una asimetría ligeramente positiva de 0.05, por lo que los valores se distribuyen de forma equilibrada en torno a la media. Finalmente, se identificaron 4161 valores atípicos, lo que evidencia la presencia de registros extremos fuera de los límites de Tukey. Por todo lo anterior, la variable presión en milibares presenta una dispersión global sumamente baja, reflejando la estabilidad barométrica característica de las estaciones meteorológicas analizadas a nivel mundial.