# Librerías utilizadas para tablas, transformación y gráficas.
library(gt)
library(tidyr)
library(ggplot2)
library(knitr)
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
# Cargar el archivo de trabajo.
datos <- read.csv("dataset_geologico_limpio_80....csv",
header = TRUE, sep = ",", dec = ".",
stringsAsFactors = FALSE)
# Extraer NMODES como variable cuantitativa discreta.
nmodos <- round(as.numeric(datos$NMODES))
nmodos <- na.omit(nmodos)
nmodos <- nmodos[nmodos >= 0]
cat("Número de observaciones:", length(nmodos), "\n")
## Número de observaciones: 27784
cat("Valor mínimo:", min(nmodos), "\n")
## Valor mínimo: 0
cat("Valor máximo:", max(nmodos), "\n")
## Valor máximo: 9
NMODES representa el número de modos granulométricos
identificados en cada muestra geológica. Al ser un conteo de ocurrencias
por muestra, puede evaluarse mediante un modelo de Poisson.
Los valores del eje horizontal representan la cantidad de modos
identificados: 0 indica que no se registró ningún modo;
1, una muestra unimodal; 2, una muestra
bimodal; y 3 o más, una muestra multimodal.
# Construir la distribución de frecuencias completa.
valores <- 0:max(nmodos)
categorias <- ifelse(valores == 0, "Sin modos",
ifelse(valores == 1, "Unimodal",
ifelse(valores == 2, "Bimodal",
paste(valores, "modos"))))
ni <- table(factor(nmodos, levels = valores))
TDF <- data.frame(Valor = valores, Categoria = categorias,
ni = as.numeric(ni)) %>%
mutate(hi = ni / sum(ni) * 100,
Ni_asc = cumsum(ni),
Ni_dsc = rev(cumsum(rev(ni))),
Hi_asc = cumsum(hi),
Hi_dsc = rev(cumsum(rev(hi))))
# Incorporar la fila de comprobación de totales.
tabla_frecuencias <- TDF %>%
mutate(Valor = as.character(Valor)) %>%
rbind(data.frame(Valor = "TOTAL", Categoria = "",
ni = sum(TDF$ni), hi = 100,
Ni_asc = NA, Ni_dsc = NA, Hi_asc = NA, Hi_dsc = NA))
tabla_frecuencias %>% gt() %>%
tab_header(title = md("**Tabla N.° 1**"),
subtitle = "Distribución de frecuencias de NMODES") %>%
fmt_number(columns = c(hi, Hi_asc, Hi_dsc), decimals = 6) %>%
sub_missing(columns = everything(), missing_text = "")
| Tabla N.° 1 | |||||||
| Distribución de frecuencias de NMODES | |||||||
| Valor | Categoria | ni | hi | Ni_asc | Ni_dsc | Hi_asc | Hi_dsc |
|---|---|---|---|---|---|---|---|
| 0 | Sin modos | 6790 | 24.438526 | 6790 | 27784 | 24.438526 | 100.000000 |
| 1 | Unimodal | 9603 | 34.563058 | 16393 | 20994 | 59.001584 | 75.561474 |
| 2 | Bimodal | 6796 | 24.460121 | 23189 | 11391 | 83.461705 | 40.998416 |
| 3 | 3 modos | 3041 | 10.945148 | 26230 | 4595 | 94.406853 | 16.538295 |
| 4 | 4 modos | 1163 | 4.185862 | 27393 | 1554 | 98.592715 | 5.593147 |
| 5 | 5 modos | 301 | 1.083357 | 27694 | 391 | 99.676073 | 1.407285 |
| 6 | 6 modos | 65 | 0.233948 | 27759 | 90 | 99.910020 | 0.323927 |
| 7 | 7 modos | 19 | 0.068385 | 27778 | 25 | 99.978405 | 0.089980 |
| 8 | 8 modos | 3 | 0.010798 | 27781 | 6 | 99.989202 | 0.021595 |
| 9 | 9 modos | 3 | 0.010798 | 27784 | 3 | 100.000000 | 0.010798 |
| TOTAL | 27784 | 100.000000 | |||||
# Gráfica de la distribución observada.
# Ampliar el margen inferior para mostrar todos los nombres completos.
par(mar = c(10, 5, 4, 2))
barplot(TDF$ni, names.arg = TDF$Categoria, col = "gray75", border = "gray30",
main = "Gráfica N.° 1\nDistribución del número de modos granulométricos",
xlab = "", ylab = "Frecuencia absoluta",
las = 2, cex.names = 0.80)
mtext("Clasificación modal", side = 1, line = 7)
# Restaurar los márgenes predeterminados.
par(mar = c(5.1, 4.1, 4.1, 2.1))
# Estimar lambda mediante la media muestral.
lambda <- mean(nmodos)
N <- length(nmodos)
# Calcular probabilidades y frecuencias esperadas.
P_esperada <- dpois(valores, lambda = lambda)
P_esperada[length(P_esperada)] <- P_esperada[length(P_esperada)] +
(1 - ppois(max(valores), lambda = lambda))
Fe <- N * P_esperada
comparativa <- TDF %>%
mutate(Frecuencia_Esperada = Fe,
Diferencia = ni - Frecuencia_Esperada,
Error_Porcentual = abs(Diferencia) / ifelse(ni == 0, 1, ni) * 100)
comparativa %>% gt() %>%
tab_header(title = md("**Tabla N.° 2**"),
subtitle = "Frecuencias observadas y esperadas del modelo de Poisson") %>%
fmt_number(columns = c(Frecuencia_Esperada, Diferencia, Error_Porcentual), decimals = 6)
| Tabla N.° 2 | ||||||||||
| Frecuencias observadas y esperadas del modelo de Poisson | ||||||||||
| Valor | Categoria | ni | hi | Ni_asc | Ni_dsc | Hi_asc | Hi_dsc | Frecuencia_Esperada | Diferencia | Error_Porcentual |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Sin modos | 6790 | 24.43852577 | 6790 | 27784 | 24.43853 | 100.00000000 | 6,814.216803 | −24.216803 | 0.356654 |
| 1 | Unimodal | 9603 | 34.56305788 | 16393 | 20994 | 59.00158 | 75.56147423 | 9,577.035414 | 25.964586 | 0.270380 |
| 2 | Bimodal | 6796 | 24.46012093 | 23189 | 11391 | 83.46170 | 40.99841635 | 6,730.018282 | 65.981718 | 0.970890 |
| 3 | 3 modos | 3041 | 10.94514829 | 26230 | 4595 | 94.40685 | 16.53829542 | 3,152.899557 | −111.899557 | 3.679696 |
| 4 | 4 modos | 1163 | 4.18586237 | 27393 | 1554 | 98.59272 | 5.59314714 | 1,107.810024 | 55.189976 | 4.745484 |
| 5 | 5 modos | 301 | 1.08335733 | 27694 | 391 | 99.67607 | 1.40728477 | 311.394138 | −10.394138 | 3.453202 |
| 6 | 6 modos | 65 | 0.23394760 | 27759 | 90 | 99.91002 | 0.32392744 | 72.941439 | −7.941439 | 12.217599 |
| 7 | 7 modos | 19 | 0.06838468 | 27778 | 25 | 99.97840 | 0.08997984 | 14.645069 | 4.354931 | 22.920687 |
| 8 | 8 modos | 3 | 0.01079758 | 27781 | 6 | 99.98920 | 0.02159516 | 2.572863 | 0.427137 | 14.237913 |
| 9 | 9 modos | 3 | 0.01079758 | 27784 | 3 | 100.00000 | 0.01079758 | 0.466410 | 2.533590 | 84.452986 |
# Gráfica comparativa del modelo.
grafico <- comparativa %>% select(Categoria, ni, Frecuencia_Esperada) %>%
pivot_longer(cols = c(ni, Frecuencia_Esperada),
names_to = "Distribucion", values_to = "Frecuencia")
# Conservar el orden natural de las categorías: 0, 1, 2, 3, ... modos.
grafico$Categoria <- factor(
grafico$Categoria,
levels = categorias,
ordered = TRUE
)
# Mostrar primero la frecuencia observada y luego la esperada.
grafico$Distribucion <- factor(
grafico$Distribucion,
levels = c("ni", "Frecuencia_Esperada")
)
ggplot(grafico, aes(Categoria, Frecuencia, fill = Distribucion)) +
geom_col(position = "dodge") +
scale_fill_manual(values = c("ni" = "darkred", "Frecuencia_Esperada" = "darkblue"),
labels = c("Observada", "Esperada")) +
labs(title = "Gráfica N.° 2\nComparación entre frecuencias observadas y esperadas",
subtitle = paste("lambda =", round(lambda, 6)),
x = "Clasificación modal", y = "Frecuencia absoluta", fill = "Distribución") +
theme_classic() +
theme(
axis.text.x = element_text(angle = 35, hjust = 1, size = 10),
axis.title.x = element_text(margin = margin(t = 12)),
legend.position = "bottom",
plot.margin = margin(10, 20, 20, 10)
)
# Correlación de Pearson entre frecuencias relativas.
Fo_rel <- comparativa$ni / sum(comparativa$ni)
Fe_rel <- comparativa$Frecuencia_Esperada / sum(comparativa$Frecuencia_Esperada)
coef_pearson <- cor(Fo_rel, Fe_rel, method = "pearson")
plot(Fo_rel, Fe_rel, pch = 19, col = "darkblue", cex = 1.25,
xlab = "Frecuencia relativa observada",
ylab = "Frecuencia relativa esperada",
main = "Gráfica N.° 3\nCorrelación observada y esperada",
xlim = c(0, max(Fo_rel) * 1.15), ylim = c(0, max(Fe_rel) * 1.15))
abline(0, 1, col = "red", lwd = 2)
cat("Coeficiente de Pearson:", round(coef_pearson, 6), "\n")
## Coeficiente de Pearson: 0.999911
cat("Porcentaje de ajuste:", round(coef_pearson * 100, 2), "%\n")
## Porcentaje de ajuste: 99.99 %
# Agrupar clases consecutivas cuando la frecuencia esperada sea menor que cinco.
Fo_chi <- c(); Fe_chi <- c(); fo_temp <- 0; fe_temp <- 0
for (i in 1:length(Fe)) {
fo_temp <- fo_temp + comparativa$ni[i]
fe_temp <- fe_temp + Fe[i]
if (fe_temp >= 5) {
Fo_chi <- c(Fo_chi, fo_temp); Fe_chi <- c(Fe_chi, fe_temp)
fo_temp <- 0; fe_temp <- 0
}
}
if (fe_temp > 0) {
ultimo <- length(Fe_chi)
Fo_chi[ultimo] <- Fo_chi[ultimo] + fo_temp
Fe_chi[ultimo] <- Fe_chi[ultimo] + fe_temp
}
Chi2 <- sum((Fo_chi - Fe_chi)^2 / Fe_chi)
gl <- max(length(Fo_chi) - 2, 1)
p_valor <- 1 - pchisq(Chi2, gl)
cat("Estadístico chi-cuadrado:", round(Chi2, 6), "\n")
## Estadístico chi-cuadrado: 11.76219
cat("Grados de libertad:", gl, "\n")
## Grados de libertad: 6
cat("P-valor:", round(p_valor, 6), "\n")
## P-valor: 0.067489
if (p_valor > 0.05) cat("No se rechaza H0: el ajuste es adecuado.\n")
## No se rechaza H0: el ajuste es adecuado.
5.1 PROBABILIDAD PUNTUAL
# Seleccionar como referencia el número esperado de modos.
x <- round(lambda)
categoria_x <- ifelse(x == 0, "Sin modos",
ifelse(x == 1, "Unimodal",
ifelse(x == 2, "Bimodal", paste(x, "modos"))))
# Calcular la probabilidad de observar exactamente esa categoría.
prob_puntual <- dpois(x, lambda)
cat("P(X =", x, ") =", round(prob_puntual, 6), "\n")
## P(X = 1 ) = 0.344696
cat("Interpretación: probabilidad de obtener una muestra", categoria_x, "\n")
## Interpretación: probabilidad de obtener una muestra Unimodal
5.2 PROBABILIDAD ACUMULADA
# Calcular la probabilidad de observar como máximo x modos.
prob_acumulada <- ppois(x, lambda)
cat("P(X <=", x, ") =", round(prob_acumulada, 6), "\n")
## P(X <= 1 ) = 0.589953
cat("Interpretación: probabilidad de identificar", x,
"modos o menos en una muestra.\n")
## Interpretación: probabilidad de identificar 1 modos o menos en una muestra.
5.3 PROBABILIDAD COMPLEMENTARIA
# Calcular la probabilidad de observar más de x modos.
prob_complementaria <- 1 - ppois(x, lambda)
cat("P(X >", x, ") =", round(prob_complementaria, 6), "\n")
## P(X > 1 ) = 0.410047
cat("Interpretación: probabilidad de identificar más de", x,
"modos en una muestra.\n")
## Interpretación: probabilidad de identificar más de 1 modos en una muestra.
5.4 TABLA RESUMEN DE PROBABILIDADES
tabla_probabilidades <- data.frame(
Tipo = c("Puntual", "Acumulada", "Complementaria"),
Evento = c(paste("Muestra", categoria_x),
paste(x, "modos o menos"),
paste("Más de", x, "modos")),
Probabilidad = c(prob_puntual, prob_acumulada, prob_complementaria)
)
tabla_probabilidades %>% gt() %>%
fmt_number(columns = Probabilidad, decimals = 6)
| Tipo | Evento | Probabilidad |
|---|---|---|
| Puntual | Muestra Unimodal | 0.344696 |
| Acumulada | 1 modos o menos | 0.589953 |
| Complementaria | Más de 1 modos | 0.410047 |
# Intervalos normales para la media del conteo.
error <- sd(nmodos) / sqrt(length(nmodos))
tabla_ic <- data.frame(
Nivel = c("68%", "95%", "99%"),
Limite_Inferior = mean(nmodos) - c(1, 1.96, 2.576) * error,
Limite_Superior = mean(nmodos) + c(1, 1.96, 2.576) * error)
tabla_ic %>% gt() %>% fmt_number(columns = 2:3, decimals = 6)
| Nivel | Limite_Inferior | Limite_Superior |
|---|---|---|
| 68% | 1.398331 | 1.412567 |
| 95% | 1.391497 | 1.419401 |
| 99% | 1.387112 | 1.423786 |
La variable número de modos granulométricos
(NMODES) se explica mediante un modelo de Poisson, con una
media aritmética de 1.41 modos por muestra y una desviación estándar de
1.19. El parámetro lambda representa el número promedio de modos
identificados en cada muestra geológica.
De esta manera se calcularon probabilidades como, por ejemplo, que al seleccionar aleatoriamente una muestra geológica, la probabilidad de identificar exactamente 1 modo es de 34.47 %, mientras que la probabilidad de identificar 1 modo o menos es de 59 %.
Mediante el teorema del límite central, se estima que la media poblacional del número de modos granulométricos se encuentra entre 1.39 y 1.42 modos, con un 95 % de confianza. La prueba chi-cuadrado obtuvo un p-valor de 0.0675; al ser superior a 0.05, no se rechaza la hipótesis nula y el modelo de Poisson se considera adecuado.