0.Librerias

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

1.Leer Datos

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

2. Extraccisn y Depuracisn de la Variable aleatoria

Celsius <- na.omit(variables$temperature_celsius)

# Total de datos

n_total <- length(Celsius)

3. Frecuencias

3.1 Max y Min

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

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: 6.061111

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(
      Celsius >= Li1[i] &
        Celsius <= Ls1[i]
    )
    
  } else {
    
    ni1[i] <- sum(
      Celsius >= Li1[i] &
        Celsius < 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 ajustada para tabla simplificada

amplitud <- 15

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

Ls2 <- Li2 + 15

#Frecuencias

ni2 <- numeric(length(Li2))

for(i in 1:length(Li2)){
  
  if(i == length(Li2)){
    
    ni2[i] <- sum(
      Celsius >= Li2[i] &
        Celsius <= Ls2[i]
    )
    
  } else {
    
    ni2[i] <- sum(
      Celsius >= Li2[i] &
        Celsius < 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 simplificada

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

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

# Mostrar tabla

kable(
  TDF_Celsius,
  align = "c",
  caption = "Tabla N1: Distribución de frecuencias agrupadas de la 
  temperatura °C 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_Celsius),
    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 N1: Distribución de frecuencias agrupadas de la temperatura °C 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
-30 -15 -22.5 315 0.22 315 0.22 141703 100
-15 0 -7.5 3361 2.37 3676 2.59 141388 99.78
0 15 7.5 29162 20.58 32838 23.17 138027 97.41
15 30 22.5 88135 62.2 120973 85.37 108865 76.83
30 45 37.5 20567 14.51 141540 99.88 20730 14.63
45 60 52.5 162 0.11 141702 100 163 0.12
60 75 67.5 0 0 141702 100 1 0
75 90 82.5 1 0 141703 100 1 0
TOTAL 141703 100
Nota: Elaborado por Grupo 2.
Fuente: Global Weather Repository.

4.2. Gráficos de Distribución de Frecuencias

## Histograma original (hi)

barplot(
  hi2,
  
  names.arg = paste(Li2, Ls2, sep = " a "),
  
  
  main = "Gráfico N°1. Distribución de frecuencias relativas de la 
  Temperatura Celsius de los registros meteorológicos mundiales agrupados en 
  intervalos de 15°, período 2024–2026",
  
  xlab = "Intervalos de Celsius",
  
  ylab = "Frecuencia Relativa (%)",
  
  col = "skyblue",
  
  las = 2,
  space = 0
)

5. Conjetura del modelo

5.1. Conjetura

# La temperatura en °C presenta una tendencia similar a una distribución normal

# Hipótesis nula (H0):
# La temperatura Celsius sigue una distribución Normal N(µ, σ)

# Hipótesis alternativa (H1):
# La temperatura Celsius no sigue una distribución Normal

# Parámetros del modelo normal

5.2. Cálulo de párametros

mu <- mean(Celsius, na.rm = TRUE)

sigma <- sd(Celsius, na.rm = TRUE)

mu
## [1] 21.24075
sigma
## [1] 9.64474

6. Realidad vs Modelo

6.1. Densidad

A2 <- 15

# Frecuencias relativas en porcentaje
hi <- (ni2 / sum(ni2)) * 100

# Rango de la curva normal
x <- seq(min(Li2), max(Ls2), by = 0.01)

# Densidad normal ajustada a porcentaje
y <- dnorm(x, mean = mu, sd = sigma) * 100 * A2

6.2. Gráfico

plot(
  NA,
  xlim = range(c(Li2, Ls2)),
  ylim = c(0, max(c(hi, y))*1.1),
  
  main = "Gráfica N°2: Comparación de la distribución real de la temperatura con el modelo normal",
  
  xlab = "Temperatura Celsius (°C)",
  
  ylab = "Frecuencia relativa (%)"
)


# Histograma manual en porcentaje

rect(
  xleft = Li2,
  
  ybottom = 0,
  
  xright = Ls2,
  
  ytop = hi,
  
  col = "grey",
  
  border = "white"
)


# Curva normal teórica

lines(
  x,
  y,
  
  col = "blue",
  
  lwd = 4
)

7. Aplicación de test de bondad

7.1. Pearson

# Frecuencia observada
Fo <- ni2


# Número de intervalos
h <- length(Fo)


# Probabilidades teóricas por intervalo

P <- numeric(h)

for(i in 1:h){
  
  P[i] <- pnorm(Ls2[i], mu, sigma) -
    pnorm(Li2[i], mu, sigma)
}


# Frecuencias esperadas

Fe <- P * length(Celsius)


# Correlación entre frecuencias

Correlacion <- cor(Fo, Fe) * 100

Correlacion
## [1] 99.2285

7.2. Chi cuadrado

nivel_significancia <- 0.05

# Frecuencias observadas en porcentaje

Fo_porcentaje <- (ni2 / sum(ni2)) * 100


# Frecuencias esperadas en porcentaje

Fe_porcentaje <- P * 100


# Estadístico Chi-cuadrado

X2 <- sum((Fe_porcentaje - Fo_porcentaje)^2 /
            Fe_porcentaje)

X2
## [1] 8.768549
# Grados de libertad

grados_libertad <- length(ni2) - 1


# Valor crítico

X2_critico <- qchisq(
  1 - nivel_significancia,
  grados_libertad
)

X2_critico
## [1] 14.06714
# Decisión

X2 < X2_critico
## [1] TRUE

8. Cálculo de probabilidades

8.1.¿Qué probabilidad existe de que la temperatura esté entre 15 °C y 30 °C?

prob1 <- pnorm(30, mu, sigma) -
  pnorm(15, mu, sigma)

prob1 * 100
## [1] 55.93152

8.2. ¿Qué probabilidad existe de que la temperatura sea mayor a 35 °C?

prob2 <- 1 - pnorm(35, mu, sigma)

prob2 * 100
## [1] 7.68466
n_muestra <- 100

8.3. Si se seleccionan 100 ciudades al azar, ¿cuántas se espera que tengan temperaturas entre 20°C y 25°C?

prob3 <- pnorm(25, mu, sigma) -
  pnorm(20, mu, sigma)


esperadas <- prob3 * n_muestra

esperadas
## [1] 20.28283

8.4.Gráficas de probabilidad

# Secuencia de valores para la curva normal

x <- seq(
  min(Celsius),
  max(Celsius),
  by = 0.01
)

# Curva de densidad normal

plot(
  x,
  dnorm(x, mu, sigma),
  type = "l",
  col = "blue",
  lwd = 3,
  
  main = "Gráfica N°5: Cálculo de probabilidades del modelo normal de temperatura",
  
  xlab = "Temperatura (°C)",
  
  ylab = "Densidad de probabilidad"
)


# Área roja: Temperaturas entre 15 °C y 30 °C

x_rojo <- seq(15, 30, by = 0.01)

y_rojo <- dnorm(
  x_rojo,
  mean = mu,
  sd = sigma
)

polygon(
  c(x_rojo, rev(x_rojo)),
  c(y_rojo, rep(0, length(y_rojo))),
  col = rgb(1, 0, 0, 0.5),
  border = NA
)


# Área verde: Temperaturas mayores a 35 °C

x_verde <- seq(35, max(Celsius), by = 0.01)

y_verde <- dnorm(
  x_verde,
  mean = mu,
  sd = sigma
)

polygon(
  c(x_verde, rev(x_verde)),
  c(y_verde, rep(0, length(y_verde))),
  col = rgb(0, 1, 0, 0.5),
  border = NA
)


# Líneas de referencia

abline(v = c(15, 30, 35),
       lty = 2,
       lwd = 2)


# Leyenda

legend(
  "topright",
  
  legend = c(
    "Modelo normal",
    "15°C a 30°C",
    "Mayor a 35°C"
  ),
  
  col = c(
    "blue",
    "red",
    "green"
  ),
  
  lwd = 3,
  
  fill = c(
    NA,
    rgb(1,0,0,0.5),
    rgb(0,1,0,0.5)
  ),
  
  cex = 0.8
)

# Temperaturas entre 15 y 30 °C

P1 <- pnorm(30, mu, sigma) - pnorm(15, mu, sigma)

P1 * 100
## [1] 55.93152
# Temperaturas mayores a 35 °C

P2 <- 1 - pnorm(35, mu, sigma)

P2 * 100
## [1] 7.68466
text(22.5, 0.015,
     paste("P =", round(P1*100, 2), "%"))

text(45, 0.005,
     paste("P =", round(P2*100, 2), "%"))

9. Intevarlo de Confianza

# Parámetros de la temperatura Celsius
media_Celsius <- mean(Celsius)
sigma_Celsius <- sd(Celsius)
n_Celsius <- length(Celsius)

# Error para un nivel de confianza aproximado del 95 %
error_Celsius <- 2 * (sigma_Celsius / sqrt(n_Celsius))

# Límites del intervalo de confianza
limite_inf_Celsius <- round(media_Celsius - error_Celsius, 2)
limite_sup_Celsius <- round(media_Celsius + error_Celsius, 2)

# Crear tabla del intervalo
IC_Celsius <- data.frame(
  
  "Nivel de confianza" = "95%",
  
  "Intervalo de confianza de µ (°C)" = paste0(
    limite_inf_Celsius,
    " < µ < ",
    limite_sup_Celsius
  ),
  
  "Desviación estándar (°C)" = round(sigma_Celsius,2)
)

# Convertir a texto
IC_Celsius[] <- lapply(IC_Celsius, as.character)

# Mostrar tabla con el mismo estilo que la TDF

kable(
  IC_Celsius,
  align = "c",
  caption = "Tabla N°2: Intervalo de confianza de la temperatura Celsius de los registros meteorológicos mundiales con un nivel de confianza del 95%, 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(
    1,
    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 N°2: Intervalo de confianza de la temperatura Celsius de los registros meteorológicos mundiales con un nivel de confianza del 95%, período 2024–2026
Nivel.de.confianza Intervalo.de.confianza.de.µ…C. Desviación.estándar…C.
95% 21.19 < µ < 21.29 9.64
Nota: Elaborado por Grupo 2. Fuente: Global Weather Repository.

10. Conclusión

La variable temperatura en grados Celsius (°C) de los registros meteorológicos mundiales se explica de forma adecuada mediante un modelo de distribución normal con parámetros μ=22.45 °C y σ=10.32 °C. Asimismo, con base en las pruebas de bondad de ajuste y los análisis estadísticos realizados, se puede afirmar con un 95% de confianza que la media verdadera de la temperatura global se encuentra entre 22.38 °C y 22.52 °C, presentando una desviación estándar muestral de 10.32 °C, lo que evidencia la dispersión natural de las condiciones térmicas registradas a nivel mundial.