0. 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
1. Carga de datos
df <- read.csv(
"waterPollution.csv",
header = TRUE,
sep = ",",
stringsAsFactors = FALSE
)
2. Selección de la variable
# Extraer variable
Venue <- df$VenueCount
# Eliminar valores faltantes
Venue <- Venue[!is.na(Venue)]
3. Tabla de distribución de frecuencias
# ==========================================
# TABLA DE DISTRIBUCIÓN DE FRECUENCIAS
# ==========================================
tabla_freq <- as.data.frame(
table(Venue)
)
tabla_freq <- tabla_freq[
order(as.numeric(as.character(tabla_freq$Venue))),
]
colnames(tabla_freq) <- c(
"Venue",
"ni"
)
N <- sum(tabla_freq$ni)
tabla_freq$hi <- round(
tabla_freq$ni / N * 100,
2
)
tabla_freq$p_s <- round(
tabla_freq$ni / N,
4
)
fila_total <- data.frame(
Venue = "TOTAL",
ni = N,
hi = 100,
p_s = round(sum(tabla_freq$p_s),4)
)
tabla_final <- rbind(
tabla_freq,
fila_total
)
tabla_final %>%
gt() %>%
tab_header(
title = md("**Tabla N°1**"),
subtitle = md(
"**Distribución de frecuencias original de Venue Count**"
)
) %>%
cols_label(
Venue = "Venue Count",
ni = "ni",
hi = "hi (%)",
p_s = "p(s)"
) %>%
tab_style(
style = cell_text(weight = "bold"),
locations = cells_body(
rows = Venue == "TOTAL"
)
) %>%
opt_row_striping()
| Tabla N°1 |
| Distribución de frecuencias original de Venue Count |
| Venue Count |
ni |
hi (%) |
p(s) |
| 0 |
19410 |
97.05 |
0.9705 |
| 1 |
129 |
0.64 |
0.0064 |
| 2 |
113 |
0.56 |
0.0056 |
| 3 |
77 |
0.38 |
0.0039 |
| 4 |
114 |
0.57 |
0.0057 |
| 5 |
65 |
0.32 |
0.0032 |
| 6 |
38 |
0.19 |
0.0019 |
| 7 |
17 |
0.08 |
0.0008 |
| 8 |
5 |
0.03 |
0.0003 |
| 9 |
6 |
0.03 |
0.0003 |
| 11 |
1 |
0.00 |
0.0000 |
| 14 |
4 |
0.02 |
0.0002 |
| 15 |
1 |
0.00 |
0.0000 |
| 16 |
3 |
0.01 |
0.0001 |
| 18 |
2 |
0.01 |
0.0001 |
| 19 |
2 |
0.01 |
0.0001 |
| 22 |
1 |
0.00 |
0.0000 |
| 24 |
2 |
0.01 |
0.0001 |
| 31 |
1 |
0.00 |
0.0000 |
| 33 |
1 |
0.00 |
0.0000 |
| 65 |
2 |
0.01 |
0.0001 |
| 84 |
3 |
0.01 |
0.0001 |
| 100 |
3 |
0.01 |
0.0001 |
| TOTAL |
20000 |
100.00 |
0.9995 |
4. Gráfica de distribución de frecuencias
# ==========================================
# GRÁFICA DE DISTRIBUCIÓN DE FRECUENCIAS
# ==========================================
# Número de barras
n <- length(tabla_freq$Venue)
# Paleta de colores
colores <- colorRampPalette(
c("lightgreen","forestgreen")
)(n)
# Límite del eje Y
ylim_local <- c(
0,
max(tabla_freq$hi) * 1.10
)
# Gráfico de barras
barplot(
height = tabla_freq$hi,
names.arg = tabla_freq$Venue,
main = "Gráfica N°1: Distribución porcentual de Venue Count\nEstudio de contaminación del agua en Europa",
xlab = "Venue Count",
ylab = "Porcentaje",
col = colores,
ylim = ylim_local,
las = 1,
cex.names = 0.9,
cex.main = 0.9
)
abline(
h = pretty(c(0, max(tabla_freq$hi))),
col = "gray80",
lty = 2
)
box()

5. Tratamiento de datos
# ==================================================
# TRATAMIENTO DE DATOS
# ==================================================
# La distribución original presenta una elevada
# concentración de observaciones con valor 0.
# Para el ajuste del modelo de Poisson se trabajará
# únicamente con los valores comprendidos entre 1 y 10,
# ya que representan las categorías de interés para
# el análisis.
# Tratamiento de la variable
Venue_tratado <- Venue[
Venue >= 1 &
Venue <= 10
]
# ==========================================
# TABLA DE FRECUENCIAS TRATADA
# ==========================================
tabla_freq_tratada <- as.data.frame(
table(Venue_tratado)
)
tabla_freq_tratada <- tabla_freq_tratada[
order(as.numeric(as.character(tabla_freq_tratada$Venue_tratado))),
]
colnames(tabla_freq_tratada) <- c(
"Venue",
"ni"
)
# Total
N_tratado <- sum(tabla_freq_tratada$ni)
# Frecuencia relativa
tabla_freq_tratada$hi <- round(
tabla_freq_tratada$ni / N_tratado * 100,
2
)
# Probabilidad observada
tabla_freq_tratada$p_s <- round(
tabla_freq_tratada$ni / N_tratado,
4
)
# ------------------------------------------
# Fila TOTAL
# ------------------------------------------
fila_total <- data.frame(
Venue = "TOTAL",
ni = N_tratado,
hi = 100,
p_s = round(sum(tabla_freq_tratada$p_s),4)
)
tabla_final_tratada <- rbind(
tabla_freq_tratada,
fila_total
)
# ------------------------------------------
# Tabla GT
# ------------------------------------------
tabla_final_tratada %>%
gt() %>%
tab_header(
title = md("**Tabla N°2**"),
subtitle = md(
"**Distribución de frecuencias tratada para el ajuste del modelo de Poisson**"
)
) %>%
cols_label(
Venue = "Venue Count",
ni = "ni",
hi = "hi (%)",
p_s = "p(s)"
) %>%
tab_style(
style = cell_text(weight = "bold"),
locations = cells_body(
rows = Venue == "TOTAL"
)
) %>%
opt_row_striping()
| Tabla N°2 |
| Distribución de frecuencias tratada para el ajuste del modelo de Poisson |
| Venue Count |
ni |
hi (%) |
p(s) |
| 1 |
129 |
22.87 |
0.2287 |
| 2 |
113 |
20.04 |
0.2004 |
| 3 |
77 |
13.65 |
0.1365 |
| 4 |
114 |
20.21 |
0.2021 |
| 5 |
65 |
11.52 |
0.1152 |
| 6 |
38 |
6.74 |
0.0674 |
| 7 |
17 |
3.01 |
0.0301 |
| 8 |
5 |
0.89 |
0.0089 |
| 9 |
6 |
1.06 |
0.0106 |
| TOTAL |
564 |
100.00 |
0.9999 |
# ==========================================
# GRÁFICA DE LA DISTRIBUCIÓN TRATADA
# ==========================================
barplot(
tabla_freq_tratada$hi,
names.arg = tabla_freq_tratada$Venue,
main = "Gráfica N°2: Distribución porcentual de Venue Count\nTratamiento de datos para el modelo de Poisson",
xlab = "Venue Count",
ylab = "Frecuencia relativa (%)",
col = "lightgreen",
border = "black",
ylim = c(0, max(tabla_freq_tratada$hi) * 1.10),
las = 1
)
grid(
nx = NA,
ny = NULL,
lty = 2,
col = "gray80"
)
box()

5. Conjetura
# Se conjetura que la variable Venue Count presenta un comportamiento
# compatible con una distribución de Poisson, debido a que corresponde
# a una variable discreta de conteo y la mayor concentración de
# observaciones se encuentra en valores bajos, disminuyendo su
# frecuencia conforme aumenta el número de establecimientos. Esta
# conjetura será verificada mediante las pruebas de bondad de ajuste.
6. Parámetro
# ==========================================
# PARÁMETRO λ
# ==========================================
# Valores de Venue Count
x_mapped <- as.numeric(
as.character(tabla_freq_tratada$Venue)
)
# Probabilidades observadas
p_s_data <- tabla_freq_tratada$p_s
# Esperanza matemática (λ)
lambda <- sum(
x_mapped * p_s_data
)
cat(
"Lambda =",
round(lambda,4),
"\n"
)
## Lambda = 3.2051
7. Sobreposición de la realidad con el modelo de Poisson
# ==========================================
# PROBABILIDADES TEÓRICAS
# ==========================================
# Valores tratados
x_mapped <- as.numeric(as.character(tabla_freq_tratada$Venue))
# Probabilidades observadas
p_s_data <- tabla_freq_tratada$p_s
# Parámetro lambda
lambda <- sum(x_mapped * p_s_data)
# Probabilidades teóricas de Poisson
prob_poisson <- dpois(
x = x_mapped,
lambda = lambda
)
# Convertir a porcentaje
hi_poisson <- prob_poisson * 100
# Mostrar probabilidades
comparacion_poisson <- data.frame(
Venue = tabla_freq_tratada$Venue,
Realidad = round(tabla_freq_tratada$hi, 2),
Poisson = round(hi_poisson, 2)
)
comparacion_poisson
## Venue Realidad Poisson
## 1 1 22.87 13.00
## 2 2 20.04 20.83
## 3 3 13.65 22.25
## 4 4 20.21 17.83
## 5 5 11.52 11.43
## 6 6 6.74 6.11
## 7 7 3.01 2.80
## 8 8 0.89 1.12
## 9 9 1.06 0.40
# ==========================================
# COMPARACIÓN
# ==========================================
datos_poisson <- rbind(
Realidad = tabla_freq_tratada$hi,
`Modelo Poisson` = hi_poisson
)
# ==========================================
# GRÁFICA
# ==========================================
par(mar = c(6.5,4.5,4.5,2))
barplot(
datos_poisson,
beside = TRUE,
names.arg = tabla_freq_tratada$Venue,
col = c("steelblue","firebrick"),
main = "Gráfica N°3: Comparación de la realidad con el modelo de Poisson\nVenue Count",
xlab = "Venue Count",
ylab = "Porcentaje",
ylim = c(0, max(datos_poisson) * 1.25),
las = 1,
cex.names = 0.9
)
abline(
h = pretty(c(0, max(datos_poisson))),
col = "gray80",
lty = 2
)
legend(
"topright",
legend = c("Realidad", "Modelo Poisson"),
fill = c("steelblue", "firebrick"),
bty = "n"
)
box()

9.1 Test de Pearson
# ==========================================
# TEST DE PEARSON
# ==========================================
# Probabilidades teóricas
P_teorica <- hi_poisson / 100
# Frecuencias observadas
fo_pearson <- tabla_freq_tratada$ni
# Total de observaciones
N <- sum(fo_pearson)
# Frecuencias esperadas
fe_pearson <- N * P_teorica
# Coeficiente de Pearson
Coef_Pearson <- cor(
fo_pearson,
fe_pearson
) * 100
cat(
"Coeficiente de Pearson (%):",
round(Coef_Pearson,2),
"\n"
)
## Coeficiente de Pearson (%): 84.93
9.2 Test Chi-cuadrado
# ==========================================
# TEST CHI-CUADRADO
# ==========================================
# Total de observaciones
N_chi <- sum(tabla_freq_tratada$ni)
# Frecuencias relativas observadas
fo <- tabla_freq_tratada$ni / N_chi
# Número de categorías
k <- length(fo)
# Probabilidades teóricas
fe <- dpois(
x_mapped,
lambda
)
# Estadístico Chi-cuadrado
Chi_Calculado <- sum(
(fo - fe)^2 / fe
)
# Grados de libertad
gl <- k - 1
# Valor crítico
Chi_Critico <- qchisq(
0.95,
df = gl
)
cat(
"Chi Calculado:",
round(Chi_Calculado,4),
"\n"
)
## Chi Calculado: 0.1241
cat(
"Chi Crítico:",
round(Chi_Critico,4),
"\n"
)
## Chi Crítico: 15.5073
if(Chi_Calculado < Chi_Critico){
cat(
"\nNo se rechaza H0: El modelo de Poisson es adecuado.\n"
)
}else{
cat(
"\nSe rechaza H0: El modelo de Poisson no es adecuado.\n"
)
}
##
## No se rechaza H0: El modelo de Poisson es adecuado.
10. Cálculo de probabilidades
# ==============================================================================
# 10. CÁLCULO DE PROBABILIDADES
# ==============================================================================
# --------------------------------------
# PREGUNTA DE PORCENTAJE
# ¿Cuál es la probabilidad de que Venue Count
# sea menor o igual a 3?
# --------------------------------------
prob_3 <- ppois(
q = 3,
lambda = lambda
)
prob_3_porcentaje <- prob_3 * 100
cat(
"Probabilidad de que Venue Count sea menor o igual a 3:",
round(prob_3_porcentaje, 2),
"%\n"
)
## Probabilidad de que Venue Count sea menor o igual a 3: 60.14 %
# --------------------------------------
# PREGUNTA DE CANTIDAD
# ¿Cuántas observaciones se espera que tengan
# Venue Count menor o igual a 3?
# --------------------------------------
cantidad_esperada <- prob_3 * length(Venue_tratado)
cat(
"Cantidad esperada de observaciones:",
round(cantidad_esperada),
"observaciones\n"
)
## Cantidad esperada de observaciones: 339 observaciones
# --------------------------------------
# PREGUNTA DE INTERVALO
# ¿Cuál es la probabilidad de que Venue Count
# se encuentre entre 2 y 4?
# --------------------------------------
prob_2_4 <- (
ppois(4, lambda = lambda) -
ppois(1, lambda = lambda)
) * 100
cat(
"Probabilidad entre 2 y 4:",
round(prob_2_4, 2),
"%\n"
)
## Probabilidad entre 2 y 4: 60.92 %
# ==============================================================================
# DEMOSTRACIÓN GRÁFICA
# ==============================================================================
# Valores posibles
x <- 0:10
# Probabilidades del modelo de Poisson
y <- dpois(
x,
lambda = lambda
) * 100
# Colores de las barras
colores <- rep("orange", length(x))
# Verde para P(X ≤ 3)
colores[x <= 3] <- "darkgreen"
# Azul para P(2 ≤ X ≤ 4)
colores[x >= 2 & x <= 4] <- "blue"
# Gráfico
barplot(
height = y,
names.arg = x,
col = colores,
border = "black",
ylim = c(0, max(y) * 1.25),
main = "Gráfica N°4: Cálculo de Probabilidades\nModelo de Poisson",
xlab = "Venue Count",
ylab = "Probabilidad (%)"
)
grid(
nx = NA,
ny = NULL,
lty = 2,
col = "gray80"
)
legend(
"topright",
legend = c(
"Modelo de Poisson",
"P(Venue ≤ 3)",
"P(2 ≤ Venue ≤ 4)"
),
fill = c(
"orange",
"darkgreen",
"blue"
),
bty = "o",
bg = "white"
)
box()

11. intervalo confianza
# ==============================================================================
# 11. INTERVALO DE CONFIANZA
# ==============================================================================
# Variable tratada
Venue_num <- Venue_tratado
# Media
media_venue <- mean(Venue_num)
# Desviación estándar
desviacion_venue <- sd(Venue_num)
# Tamaño de muestra
n_venue <- length(Venue_num)
# Nivel de confianza del 95%
error_venue <- 1.96 * (
desviacion_venue /
sqrt(n_venue)
)
# Límites del intervalo
limite_inferior <- round(
media_venue - error_venue,
2
)
limite_superior <- round(
media_venue + error_venue,
2
)
# Crear tabla
tabla_intervalo <- data.frame(
Intervalo = paste0(
"P [",
limite_inferior,
" < μ < ",
limite_superior,
"] = 95%"
)
)
# Mostrar tabla
tabla_intervalo %>%
gt() %>%
tab_header(
title = md("**Tabla N°3**"),
subtitle = md(
"**Intervalo de confianza para Venue Count**"
)
) %>%
opt_row_striping()
| Tabla N°3 |
| Intervalo de confianza para Venue Count |
| Intervalo |
| P [3.05 < μ < 3.36] = 95% |