1. Carga de datos

library(knitr)
library(kableExtra)
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following object is masked from 'package:kableExtra':
## 
##     group_rows
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(e1071)

# Carga de datos
datos <- read.csv("china_water_pollution_data.csv", header = TRUE, sep = ",", dec = ".")

2. Extracción de Variable

# Variable: Coliform_Count_CFU_100mL
Coliformes <- as.numeric(as.character(datos$Coliform_Count_CFU_100mL))
Coliformes <- na.omit(Coliformes)
Coliformes <- Coliformes[Coliformes >= 0]
n <- length(Coliformes)

3. Tabla de Distribución de Frecuencia

Hist_Colif <- hist(Coliformes, breaks = 8, plot = FALSE)
Li <- Hist_Colif$breaks[1:(length(Hist_Colif$breaks)-1)]
Ls <- Hist_Colif$breaks[2:length(Hist_Colif$breaks)]
ni <- Hist_Colif$counts

if(sum(ni) != n) ni[which.max(ni)] <- ni[which.max(ni)] + (n - sum(ni))

Mc <- Hist_Colif$mids
hi_val <- (ni/sum(ni)) * 100

TDF_Colif <- data.frame(
  Lim_inf = Li, Lim_sup = Ls, MC = Mc, ni = ni, 
  hi = round(hi_val, 2), Ni_asc = cumsum(ni), 
  Hi_asc = round(cumsum(hi_val), 2)
)

kable(TDF_Colif, align = 'c', caption = "Tabla de Frecuencias de Recuento de Coliformes (UFC/100mL)") %>%
  kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover"))
Tabla de Frecuencias de Recuento de Coliformes (UFC/100mL)
Lim_inf Lim_sup MC ni hi Ni_asc Hi_asc
60 70 65 2 0.07 2 0.07
70 80 75 63 2.10 65 2.17
80 90 85 446 14.87 511 17.03
90 100 95 1081 36.03 1592 53.07
100 110 105 960 32.00 2552 85.07
110 120 115 386 12.87 2938 97.93
120 130 125 57 1.90 2995 99.83
130 140 135 5 0.17 3000 100.00

4. Gráficas

4.1 Histograma

hist(Coliformes, breaks = 10,
     main = "Gráfica N°1: Distribución del recuento de coliformes\nChina, 2023",
     xlab = "Recuento (UFC/100mL)", ylab = "Cantidad",
     col = "skyblue", las = 1)

4.2 Conjetura del Modelo

# Lambda real de la distribución Poisson
lambda_p <- mean(Coliformes)

# Tabla de frecuencias observadas
FO_tab <- table(Coliformes)
FO <- as.numeric(FO_tab) / sum(FO_tab) * 100
codigos <- as.numeric(names(FO_tab))

# Frecuencia teórica Poisson
FE <- dpois(codigos, lambda = lambda_p) * 100

# Matriz para gráfico comparativo
matriz_p <- rbind(FO, FE)

barplot(matriz_p, beside = TRUE,
        main = "Gráfica N°2: Ajuste del Modelo Poisson al Recuento de Coliformes",
        xlab = "Recuento de coliformes (UFC/100mL)", ylab = "Porcentaje (%)",
        col = c("skyblue", "darkblue"), names.arg = codigos, las = 1)

legend("topright", legend = c("Realidad", "Modelo Poisson"), 
       fill = c("skyblue", "darkblue"), bty = "n")

5. Tests

5.1 Test de Pearson

# Evitamos valores muy pequeños
FE_adj <- FE
FE_adj[FE_adj < 0.5] <- 0.5

# Pearson
cor_pearson <- cor(FO, FE_adj) * 100

plot(FO, FE_adj,
     main = "Gráfica N°3: Correlación del modelo Poisson",
     xlab = "Frecuencia observada (%)", ylab = "Frecuencia esperada (%)",
     pch = 18, col = "darkblue",
     xlim = c(0, max(FO)*1.1), ylim = c(0, max(FE_adj)*1.1), las = 1)

modelo_lineal <- lm(FE_adj ~ 0 + FO)
abline(modelo_lineal, col = "red", lwd = 2)
text(x = max(FO)*0.3, y = max(FE_adj)*0.8, 
     labels = paste("r =", round(cor_pearson, 2), "%"), col = "red", font = 2)

### 5.2 Test de Chi cuadrado

# Chi-cuadrado
x2_p <- sum((FO - FE_adj)^2 / FE_adj)
gl_p <- length(FO) - 1
VC_p <- qchisq(0.95, gl_p) # Nivel 95%

cat("Chi-cuadrado calculado:", round(x2_p, 4), "\n")
## Chi-cuadrado calculado: 6.4957
cat("Valor Crítico:", round(VC_p, 4), "\n")
## Valor Crítico: 81.381
cat("¿Modelo aprobado?:", x2_p < VC_p)
## ¿Modelo aprobado?: TRUE

6. Calculo de Porbabilidades

## 6. Cálculo de Probabilidades 

plot(1, type = "n", axes = FALSE, xlab = "", ylab = "") 

lambda_p <- mean(Coliformes)

# Elegimos un rango cercano a lambda para que tenga valor significativo
min_val <- 95
max_val <- 105

# Probabilidad Poisson para ese rango
prob_poisson_final <- (ppois(max_val, lambda_p) - ppois(min_val - 1, lambda_p)) * 100

# Mostrar en la gráfica
text(x = 1, y = 1, 
     labels = paste("¿Cuál es la probabilidad de que\nal seleccionar al azar una muestra de\nagua, el recuento esté\nentre", 
                    min_val, "y", max_val, "?\n\nR:", round(prob_poisson_final, 2), "%"),
     cex = 1.6,  
     col = "blue",  
     font = 2) 

# Resultado en consola
print(paste("Probabilidad calculada:", round(prob_poisson_final, 2), "%"))
## [1] "Probabilidad calculada: 41.76 %"

7. Intervalos de confianza

media_real <- mean(Coliformes)
sd_real <- sd(Coliformes)
err_est <- 1.96 * (sd_real / sqrt(n))

tabla_concl <- data.frame(
  "Variable" = "Recuento Coliformes",
  "Parámetro_Lambda" = round(lambda_p, 4),
  "Pearson_Cor" = paste(round(cor_pearson, 2), "%"),
  "IC_95_Media" = paste("[", round(media_real - err_est, 2), ";", round(media_real + err_est, 2), "]"),
  "Estado" = ifelse(x2_p < VC_p, "Aprobado", "No Aprobado")
)

kable(tabla_concl, align = 'c', caption = "Tabla 1. Conclusiones del Modelo Poisson") %>%
  kable_styling(full_width = FALSE, bootstrap_options = "bordered")
Tabla 1. Conclusiones del Modelo Poisson
Variable Parámetro_Lambda Pearson_Cor IC_95_Media Estado
Recuento Coliformes 99.9973 98.36 % [ 99.64 ; 100.35 ] Aprobado

8. Conclusión

La variable “Recuento de Coliformes (UFC/100mL)” se ajusta satisfactoriamente a un modelo de Poisson con parámetro λ = 99.9973. El test de correlación de Pearson indica un ajuste excelente (r = 98.36 %), y podemos afirmar con un 95% de confianza que la media aritmética de esta variable se encuentra entre 99.64 y 100.35 UFC/100mL. Por lo tanto, el modelo Poisson está aprobado y representa adecuadamente la distribución de los recuentos observados en el estudio de la contaminación del agua en China 2023.