# Carga de librerías
library(gt)
library(dplyr)
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
# CARGA DE DATOS
datos <- read.csv2("china_water_pollution_data.csv",
stringsAsFactors = FALSE,
fileEncoding = "UTF-8")
# PASO 1: DEFINIR LA VARIABLE DE INTERÉS
# La variable Recuento de coliformes es una variable cuantitativa discreta porque su dominio está formado por valores enteros contables, es decir,
# D={ x|x ϵ Z+ˆ69≤x≤136}
# Cargar datos
df <- read.csv2("china_water_pollution_data.csv", stringsAsFactors = FALSE)
# Definir la variable de interés: Recuento de Coliformes
Recuento_coliformes <- df$Coliform_Count_CFU_100mL
min_val <- floor(min(Recuento_coliformes, na.rm = TRUE) / 10) * 10
max_val <- ceiling(max(Recuento_coliformes, na.rm = TRUE) / 10) * 10
breaks <- seq(min_val, max_val, by = 10)
labels <- paste0("[", head(breaks, -1), " - ", tail(breaks, -1), ")")
intervalos <- cut(Recuento_coliformes,
breaks = breaks,
include.lowest = TRUE,
right = FALSE,
labels = labels)
TDF_base <- data.frame(table(intervalos))
ni <- TDF_base$Freq
hi <- round((ni / sum(ni)) * 100, 2)
#PASO 2: TABLA DE DISTRIBUCIÓN DE FRECUENCIAS
TDF_Reducida <- data.frame(
"Intervalos de recuento de coliformes" = TDF_base$intervalos,
"ni" = ni,
"hi (%)" = hi,
check.names = FALSE
)
totales <- data.frame(
"Intervalos de recuento de coliformes" = "TOTAL",
"ni" = sum(ni),
"hi (%)" = 100.00,
check.names = FALSE
)
# Unir y mostrar con kable
library(knitr)
library(kableExtra)
##
## Adjuntando el paquete: 'kableExtra'
## The following object is masked from 'package:dplyr':
##
## group_rows
TDF_final <- rbind(TDF_Reducida, totales)
# Agregar al final de la tabla
TDF_final %>%
gt() %>%
tab_header(
title = md("*Tabla N°1*"),
subtitle = md("**Distribución de frecuencia simplificada de Recuento de Coliformes**")
) %>%
tab_source_note(
source_note = md("Autor: Grupo 1")
) %>%
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"
) %>%
# Estilo adicional: poner en negrita la fila TOTAL
tab_style(
style = cell_text(weight = "bold"),
locations = cells_body(rows = nrow(TDF_final))
)
| Tabla N°1 |
| Distribución de frecuencia simplificada de Recuento de Coliformes |
| Intervalos de recuento de coliformes |
ni |
hi (%) |
| [60 - 70) |
2 |
0.07 |
| [70 - 80) |
50 |
1.67 |
| [80 - 90) |
386 |
12.87 |
| [90 - 100) |
1043 |
34.77 |
| [100 - 110) |
1008 |
33.60 |
| [110 - 120) |
433 |
14.43 |
| [120 - 130) |
73 |
2.43 |
| [130 - 140) |
5 |
0.17 |
| TOTAL |
3000 |
100.00 |
| Autor: Grupo 1 |
#PASO 3: DIAGRAMA DE BARRAS
# Crear el gráfico de barras
hi_grafico <- TDF_Reducida$`hi (%)`
nombres_grafico <- TDF_Reducida$`Intervalos de recuento de coliformes`
# Ejecutar el barplot
bp <- barplot(hi_grafico,
main = "Gráfica N°1: Distribución porcentual del recuento de coliformes\nEstudio de calidad del agua en China, 2023",
xlab = "Recuento de coliformes (UFC/100mL)",
ylab = "Porcentaje",
col = "skyblue",
ylim = c(0, 100),
names.arg = nombres_grafico,
las = 1,
cex.names = 0.7)

# PASO 4: MAPEO DE INTERVALOS
Coliformes_map <- as.numeric(intervalos)
Coliformes_map <- na.omit(Coliformes_map)
TDF_Colif_map <- table(Coliformes_map)
Tabla_Colif_map_final <- data.frame(
"Codigo" = as.integer(names(TDF_Colif_map)),
"ni" = as.integer(TDF_Colif_map),
"hi" = round(100 * as.integer(TDF_Colif_map) / sum(TDF_Colif_map), 2),
stringsAsFactors = FALSE
)
# Fila Total
totales_map <- data.frame(
"Codigo" = "Total",
"ni" = sum(Tabla_Colif_map_final$ni),
"hi" = 100.00,
stringsAsFactors = FALSE
)
TDF_Colif_map_total <- rbind(Tabla_Colif_map_final, totales_map)
# Librería
library(gt)
library(dplyr)
TDF_Colif_map_total %>%
gt() %>%
tab_header(
title = md("Tabla N°2"),
subtitle = md("Tabla de distribución de frecuencias del Recuento de coliformes (Mapeado)")
) %>%
cols_label(
Codigo = md("**Código del Intervalo**"),
ni = md("**ni**"),
hi = md("**hi (%)**")
) %>%
tab_source_note(source_note = md("Autor: Grupo 1")) %>%
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"
) %>%
tab_style(
style = cell_text(weight = "bold"),
locations = cells_body(rows = nrow(TDF_Colif_map_total))
)
| Tabla N°2 |
| Tabla de distribución de frecuencias del Recuento de coliformes (Mapeado) |
| Código del Intervalo |
ni |
hi (%) |
| 1 |
2 |
0.07 |
| 2 |
50 |
1.67 |
| 3 |
386 |
12.87 |
| 4 |
1043 |
34.77 |
| 5 |
1008 |
33.60 |
| 6 |
433 |
14.43 |
| 7 |
73 |
2.43 |
| 8 |
5 |
0.17 |
| Total |
3000 |
100.00 |
| Autor: Grupo 1 |
# PASO 5: DIAGRAMA DE BARRAS (COLIFORMES MAPEADO) - CORREGIDO
hi_map <- Tabla_Colif_map_final$hi
codigos_map <- Tabla_Colif_map_final$Codigo
bp_map <- barplot(hi_map,
main = "Gráfica N°2: Distribución porcentual de Recuento de Coliformes (Mapeado) del estudio",
xlab = "Recuento de coliformes (Mapeado)",
ylab = "Porcentaje",
col = "lightgreen",
ylim = c(0, 100),
names.arg = codigos_map,
las = 1,
cex.names = 0.9)

#PASO 6: CONJETURA
# Se conjetura que el Recuento de Coliformes se ajusta a un modelo de probabilidad de Poisson.
# El gráfico muestra un sesgo a la derecha, donde es muy frecuente encontrar pocos coliformes
# y la probabilidad disminuye conforme el número de colonias aumenta.
#PASO 7: CÁLCULO DE PARAMETROS PARA MODELO POISSON
# 1. Cálculo de Lambda
lambda_poisson <- mean(Coliformes_map, na.rm = TRUE)
lambda_poisson
## [1] 4.540333
# 2. Cálculo de la Varianza
varianza_poisson <- var(Coliformes_map, na.rm = TRUE)
varianza_poisson
## [1] 1.068729
# 4. Generar las probabilidades teóricas basadas en el modelo
codigos_teoricos <- Tabla_Colif_map_final$Codigo
P_Poisson <- dpois(codigos_teoricos, lambda = lambda_poisson)
# Convertir a porcentaje para que sea comparable con tu hi_map
hi_teorico_poisson <- round(P_Poisson * 100, 2)
# Crear un dataframe resumen de los parámetros para el informe
Parametros_Resumen <- data.frame(
"Parametro" = c("Lambda (Media)", "Varianza", "N (Muestra)"),
"Valor" = c(round(lambda_poisson, 4), round(varianza_poisson, 4), length(Coliformes_map))
)
print(Parametros_Resumen)
## Parametro Valor
## 1 Lambda (Media) 4.5403
## 2 Varianza 1.0687
## 3 N (Muestra) 3000.0000
#PASO 8: DIAGRAMA COMPARATIVO ENTRE LA REALIDAD Y EL MODELO POISSON
P_real <- hi_map / 100
P_teorica <- dpois(codigos_map, lambda = lambda_poisson)
matriz_comparacion <- rbind(P_real, P_teorica)
bp_final <- barplot(matriz_comparacion,
main = "Gráfica N°3: Comparativa Realidad vs. Modelo Poisson del Recuento de Coliformes (Mapeado)",
xlab = "Recuento de coliformes (UFC 100mL)",
ylab = "Cantidad - Probabilidad",
col = c("skyblue", "darkblue"),
names.arg = codigos_map,
beside = TRUE,
ylim = c(0, max(matriz_comparacion) + 0.1),
las = 1)
legend("topright",
legend = c("Real", "Modelo"),
fill = c("skyblue", "darkblue"),
bty = "n")

#PASO 9: APLICACIÓN DE TEST DE PEARSON Y CHI SQUARED
# TEST DE PEARSON
Fo <- P_real
Fe <- P_teorica
Correlacion_Pearson <- cor(Fo, Fe) * 100
Correlacion_Pearson
## [1] 87.58118
# GRÁFICA DE CORRELACIÓN (PEARSON)
plot(
Fo,
Fe,
main = "Gráfica N°4: Correlación de frecuencias en el modelo Poisson del Recuento de Coliformes (Mapeado)",
xlab = "Frecuencia observada (Realidad)",
ylab = "Frecuencia esperada (Modelo Poisson)",
pch = 18,
col = "darkblue",
las = 1
)
abline(
lm(Fe ~ Fo),
col = "red",
lwd = 2
)

# TEST DE CHI-CUADRADO
Fo <- P_real # Proporciones reales (hi_map / 100)
Fe <- P_teorica # Proporciones teóricas (dpois)
x2 <- sum(((Fo - Fe)^2) / Fe)
x2
## [1] 0.5144544
vc <- qchisq(0.95, length(Fo) - 1)
vc
## [1] 14.06714
x2 < vc
## [1] TRUE
#PASO 10: CALCULO DE PROBABILIDADES
# ¿Cuál es la probabilidad de que un registro seleccionado al azar
# tenga un código de recuento igual a 2?
probabilidad_especifica <- dpois(2, lambda = lambda_poisson)
probabilidad_especifica
## [1] 0.1099775
#PASO 11: CONCLUSIONES
#La variable Recuento de Coliformes, medida en UFC/100mL, se explica a través de un modelo de Poisson con un parámtero de λ=4,54.