La variable DIA representa el dia del mes en el que fue registrado cada deslizamiento. Sus valores son enteros comprendidos entre 1 y 31, por lo que se clasifica como cuantitativa discreta.
Analizar la distribucion de los deslizamientos registrados segun el dia del mes en que ocurrieron, mediante conteos, agrupacion por Sturges, diagramas de barras, ojivas, boxplot e indicadores descriptivos.
library(readxl)
library(knitr)
archivo_dataset <- "dataset_deslizamientos_dia_hora.xlsx"
if (!file.exists(archivo_dataset)) {
stop(
paste(
"No se encontro el archivo",
archivo_dataset,
"en la carpeta de trabajo."
)
)
}
hojas_disponibles <- excel_sheets(
archivo_dataset
)
if ("Dataset_landslides" %in% hojas_disponibles) {
hoja_dataset <- "Dataset_landslides"
} else {
hoja_dataset <- hojas_disponibles[1]
}
datos <- read_excel(
archivo_dataset,
sheet = hoja_dataset
)
datos <- as.data.frame(
datos
)
resumen_dataset <- data.frame(
Elemento = c(
"Archivo utilizado",
"Hoja utilizada",
"Numero de filas",
"Numero de columnas",
"Variable analizada",
"Tipo de variable"
),
Descripcion = c(
basename(archivo_dataset),
hoja_dataset,
nrow(datos),
ncol(datos),
"Dia de ocurrencia del deslizamiento",
"Cuantitativa discreta"
)
)
knitr::kable(
resumen_dataset,
caption = "Resumen inicial del dataset"
)
| Elemento | Descripcion |
|---|---|
| Archivo utilizado | dataset_deslizamientos_dia_hora.xlsx |
| Hoja utilizada | Sheet1 |
| Numero de filas | 11033 |
| Numero de columnas | 32 |
| Variable analizada | Dia de ocurrencia del deslizamiento |
| Tipo de variable | Cuantitativa discreta |
if (!"DIA" %in% names(datos)) {
stop(
paste(
"No se encontro la columna DIA.",
"Revise que el nombre sea exactamente DIA."
)
)
}
DIA_original <- suppressWarnings(
as.numeric(datos$DIA)
)
total_registros <- length(
DIA_original
)
datos_faltantes <- sum(
is.na(DIA_original)
)
datos_fuera_dominio <- sum(
!is.na(DIA_original) &
(
DIA_original < 1 |
DIA_original > 31 |
DIA_original %% 1 != 0
)
)
DIA <- DIA_original[
!is.na(DIA_original) &
DIA_original >= 1 &
DIA_original <= 31 &
DIA_original %% 1 == 0
]
DIA <- as.integer(
DIA
)
n <- length(
DIA
)
if (n == 0) {
stop(
"No existen datos validos en la variable DIA."
)
}
tabla_extraccion <- data.frame(
Indicador = c(
"Registros originales",
"Datos faltantes",
"Datos fuera del dominio",
"Datos validos utilizados"
),
Resultado = c(
total_registros,
datos_faltantes,
datos_fuera_dominio,
n
)
)
knitr::kable(
tabla_extraccion,
caption = "Control de extraccion de la variable DIA"
)
| Indicador | Resultado |
|---|---|
| Registros originales | 11033 |
| Datos faltantes | 0 |
| Datos fuera del dominio | 0 |
| Datos validos utilizados | 11033 |
conteo_inicial <- data.frame(
Indicador = c(
"Numero de datos validos",
"Valor minimo",
"Valor maximo",
"Valores diferentes"
),
Resultado = c(
n,
min(DIA),
max(DIA),
length(unique(DIA))
)
)
knitr::kable(
conteo_inicial,
caption = "Conteo inicial de la variable DIA"
)
| Indicador | Resultado |
|---|---|
| Numero de datos validos | 11033 |
| Valor minimo | 1 |
| Valor maximo | 31 |
| Valores diferentes | 31 |
La variable DIA posee 31 valores posibles y el dataset
contiene una gran cantidad de registros. Una tabla con el conteo de cada
valor es util para la revision individual, pero para resumir la
distribucion se aplica la regla de Sturges y se construyen intervalos
agrupados.
El valor cero no se incluye porque no representa un dia del mes y se encuentra fuera del dominio de la variable:
\[ DIA=\{1,2,3,\ldots,31\} \]
La regla de Sturges se expresa como:
\[ k=1+3.322\log_{10}(n) \]
valor_sturges <- 1 +
3.322 *
log10(n)
numero_clases <- ceiling(
valor_sturges
)
valor_minimo <- min(
DIA
)
valor_maximo <- max(
DIA
)
limite_inicial <- valor_minimo - 0.5
limite_final <- valor_maximo + 0.5
rango_real <- limite_final -
limite_inicial
amplitud_clase <- rango_real /
numero_clases
limites_clase <- seq(
from = limite_inicial,
to = limite_final,
length.out = numero_clases + 1
)
limites_inferiores <- head(
limites_clase,
-1
)
limites_superiores <- tail(
limites_clase,
-1
)
marcas_clase <- (
limites_inferiores +
limites_superiores
) / 2
intervalos_texto <- paste0(
"[",
round(limites_inferiores, 2),
" ; ",
round(limites_superiores, 2),
")"
)
tabla_sturges <- data.frame(
Elemento = c(
"Numero de datos",
"Resultado de Sturges",
"Numero de clases",
"Limite inicial",
"Limite final",
"Rango real",
"Amplitud de clase"
),
Resultado = c(
n,
valor_sturges,
numero_clases,
limite_inicial,
limite_final,
rango_real,
amplitud_clase
)
)
knitr::kable(
tabla_sturges,
digits = 4,
caption = "Aplicacion de Sturges y definicion de clases"
)
| Elemento | Resultado |
|---|---|
| Numero de datos | 11033.0000 |
| Resultado de Sturges | 14.4298 |
| Numero de clases | 15.0000 |
| Limite inicial | 0.5000 |
| Limite final | 31.5000 |
| Rango real | 31.0000 |
| Amplitud de clase | 2.0667 |
Se obtuvieron 15 clases con una amplitud aproximada de 2.07 dias.
Las barras se presentan separadas para conservar la lectura de una variable discreta.
clase_dia <- cut(
DIA,
breaks = limites_clase,
include.lowest = TRUE,
right = FALSE,
dig.lab = 5
)
ni_agrupada <- as.numeric(
table(clase_dia)
)
hi_agrupada <- ni_agrupada /
n
Ni_agrupada <- cumsum(
ni_agrupada
)
porcentaje_acumulado_ascendente <- c(
0,
Ni_agrupada /
n *
100
)
porcentaje_acumulado_descendente <- c(
100,
100 -
Ni_agrupada /
n *
100
)
dias_completos <- 1:31
conteo_dias <- table(
factor(
DIA,
levels = dias_completos
)
)
tabla_individual <- data.frame(
Dia = dias_completos,
ni = as.numeric(conteo_dias)
)
tabla_individual$hi <- tabla_individual$ni /
n
knitr::kable(
tabla_individual,
digits = 4,
col.names = c(
"Dia del mes",
"ni",
"hi"
),
caption = "Tabla Nro. 1. Conteo individual de los dias de ocurrencia"
)
| Dia del mes | ni | hi |
|---|---|---|
| 1 | 341 | 0.0309 |
| 2 | 296 | 0.0268 |
| 3 | 346 | 0.0314 |
| 4 | 342 | 0.0310 |
| 5 | 347 | 0.0315 |
| 6 | 491 | 0.0445 |
| 7 | 399 | 0.0362 |
| 8 | 358 | 0.0324 |
| 9 | 361 | 0.0327 |
| 10 | 358 | 0.0324 |
| 11 | 353 | 0.0320 |
| 12 | 393 | 0.0356 |
| 13 | 313 | 0.0284 |
| 14 | 335 | 0.0304 |
| 15 | 392 | 0.0355 |
| 16 | 450 | 0.0408 |
| 17 | 388 | 0.0352 |
| 18 | 433 | 0.0392 |
| 19 | 433 | 0.0392 |
| 20 | 409 | 0.0371 |
| 21 | 369 | 0.0334 |
| 22 | 372 | 0.0337 |
| 23 | 302 | 0.0274 |
| 24 | 356 | 0.0323 |
| 25 | 324 | 0.0294 |
| 26 | 313 | 0.0284 |
| 27 | 358 | 0.0324 |
| 28 | 326 | 0.0295 |
| 29 | 306 | 0.0277 |
| 30 | 299 | 0.0271 |
| 31 | 170 | 0.0154 |
tabla_agrupada <- data.frame(
Clase = seq_len(numero_clases),
Intervalo = intervalos_texto,
ni = ni_agrupada,
hi = hi_agrupada
)
knitr::kable(
tabla_agrupada,
digits = 4,
col.names = c(
"Clase",
"Intervalo",
"ni",
"hi"
),
caption = "Tabla Nro. 2. Distribucion agrupada de los dias mediante Sturges"
)
| Clase | Intervalo | ni | hi |
|---|---|---|---|
| 1 | [0.5 ; 2.57) | 637 | 0.0577 |
| 2 | [2.57 ; 4.63) | 688 | 0.0624 |
| 3 | [4.63 ; 6.7) | 838 | 0.0760 |
| 4 | [6.7 ; 8.77) | 757 | 0.0686 |
| 5 | [8.77 ; 10.83) | 719 | 0.0652 |
| 6 | [10.83 ; 12.9) | 746 | 0.0676 |
| 7 | [12.9 ; 14.97) | 648 | 0.0587 |
| 8 | [14.97 ; 17.03) | 1230 | 0.1115 |
| 9 | [17.03 ; 19.1) | 866 | 0.0785 |
| 10 | [19.1 ; 21.17) | 778 | 0.0705 |
| 11 | [21.17 ; 23.23) | 674 | 0.0611 |
| 12 | [23.23 ; 25.3) | 680 | 0.0616 |
| 13 | [25.3 ; 27.37) | 671 | 0.0608 |
| 14 | [27.37 ; 29.43) | 632 | 0.0573 |
| 15 | [29.43 ; 31.5) | 469 | 0.0425 |
par(
mar = c(5, 5, 5, 2)
)
posiciones_cantidad <- barplot(
height = tabla_individual$ni,
names.arg = tabla_individual$Dia,
space = 0.20,
col = "#E9D8C2",
border = "#444444",
main = paste0(
"Grafica Nro. 1: Cantidad de deslizamientos\n",
"segun el dia del mes"
),
xlab = "Dia de ocurrencia",
ylab = "Cantidad",
cex.names = 0.72,
las = 1,
ylim = c(
0,
max(tabla_individual$ni) * 1.18
)
)
text(
x = posiciones_cantidad,
y = tabla_individual$ni,
labels = tabla_individual$ni,
pos = 3,
cex = 0.58,
font = 2
)
porcentaje_individual <- tabla_individual$hi *
100
par(
mar = c(5, 5, 5, 2)
)
posiciones_porcentaje <- barplot(
height = porcentaje_individual,
names.arg = tabla_individual$Dia,
space = 0.20,
col = "#CFA6B8",
border = "#444444",
main = paste0(
"Grafica Nro. 2: Porcentaje de deslizamientos\n",
"segun el dia del mes"
),
xlab = "Dia de ocurrencia",
ylab = "Porcentaje",
cex.names = 0.72,
las = 1,
ylim = c(
0,
max(porcentaje_individual) * 1.18
)
)
text(
x = posiciones_porcentaje,
y = porcentaje_individual,
labels = round(porcentaje_individual, 2),
pos = 3,
cex = 0.52,
font = 2
)
par(
mar = c(8, 5, 5, 2)
)
posiciones_agrupadas <- barplot(
height = ni_agrupada,
names.arg = intervalos_texto,
space = 0.25,
col = "#E9D8C2",
border = "#333333",
main = paste0(
"Grafica Nro. 3: Cantidad agrupada de deslizamientos\n",
"segun los intervalos obtenidos mediante Sturges"
),
xlab = "Intervalos del dia de ocurrencia",
ylab = "Cantidad",
las = 2,
cex.names = 0.62,
ylim = c(
0,
max(ni_agrupada) * 1.18
)
)
text(
x = posiciones_agrupadas,
y = ni_agrupada,
labels = ni_agrupada,
pos = 3,
cex = 0.75,
font = 2
)
puntos_ojiva <- limites_clase
par(
mar = c(5, 5, 5, 2)
)
plot(
puntos_ojiva,
porcentaje_acumulado_ascendente,
type = "o",
pch = 16,
lwd = 2,
col = "#F39C12",
main = paste0(
"Grafica Nro. 4: Distribucion acumulada porcentual\n",
"mediante ojivas ascendente y descendente"
),
xlab = "Limites de clase del dia de ocurrencia",
ylab = "Porcentaje",
xlim = range(puntos_ojiva),
ylim = c(0, 100),
las = 1
)
grid(
col = "gray85",
lty = 1
)
lines(
puntos_ojiva,
porcentaje_acumulado_ascendente,
type = "o",
pch = 16,
lwd = 2,
col = "#F39C12"
)
lines(
puntos_ojiva,
porcentaje_acumulado_descendente,
type = "o",
pch = 16,
lwd = 2,
col = "#1F45FC"
)
legend(
"bottomright",
legend = c(
"Ascendente (Menor que)",
"Descendente (Mayor que)"
),
col = c(
"#F39C12",
"#1F45FC"
),
pch = 16,
lty = 1,
lwd = 2,
bg = "white",
bty = "o"
)
par(
mar = c(5, 5, 5, 2)
)
boxplot(
DIA,
horizontal = TRUE,
col = "#A7D3E8",
border = "#222222",
outline = TRUE,
outpch = 1,
outcol = "red",
main = paste0(
"Grafica Nro. 5: Diagrama de caja y bigotes\n",
"del dia de ocurrencia"
),
xlab = "Dia de ocurrencia",
las = 1
)
frecuencia_maxima <- max(
ni_agrupada
)
limite_y_superior <- frecuencia_maxima *
1.25
posicion_boxplot <- frecuencia_maxima *
0.55
altura_boxplot <- frecuencia_maxima *
0.18
estadisticas_boxplot <- boxplot.stats(
DIA
)
bigote_inferior <- estadisticas_boxplot$stats[1]
primer_cuartil <- estadisticas_boxplot$stats[2]
mediana_boxplot <- estadisticas_boxplot$stats[3]
tercer_cuartil <- estadisticas_boxplot$stats[4]
bigote_superior <- estadisticas_boxplot$stats[5]
atipicos_boxplot <- estadisticas_boxplot$out
ancho_gap <- amplitud_clase *
0.08
par(
mar = c(5, 5, 5, 2)
)
plot(
NA,
xlim = c(limite_inicial, limite_final),
ylim = c(0, limite_y_superior),
main = paste0(
"Grafica Nro. 6: Cantidad agrupada de deslizamientos\n",
"con boxplot superpuesto"
),
xlab = "Dia de ocurrencia",
ylab = "Cantidad",
xaxt = "n",
las = 1
)
axis(
side = 1,
at = marcas_clase,
labels = round(marcas_clase, 1),
cex.axis = 0.75
)
for (i in seq_len(numero_clases)) {
rect(
xleft = limites_inferiores[i] + ancho_gap,
ybottom = 0,
xright = limites_superiores[i] - ancho_gap,
ytop = ni_agrupada[i],
col = "#E9D8C2",
border = "#333333"
)
}
text(
x = marcas_clase,
y = ni_agrupada,
labels = ni_agrupada,
pos = 3,
cex = 0.78,
font = 2
)
segments(
x0 = bigote_inferior,
y0 = posicion_boxplot,
x1 = bigote_superior,
y1 = posicion_boxplot,
lty = 2,
lwd = 1.5,
col = "#333333"
)
segments(
x0 = bigote_inferior,
y0 = posicion_boxplot - altura_boxplot * 0.18,
x1 = bigote_inferior,
y1 = posicion_boxplot + altura_boxplot * 0.18,
lwd = 1.5
)
segments(
x0 = bigote_superior,
y0 = posicion_boxplot - altura_boxplot * 0.18,
x1 = bigote_superior,
y1 = posicion_boxplot + altura_boxplot * 0.18,
lwd = 1.5
)
rect(
xleft = primer_cuartil,
ybottom = posicion_boxplot - altura_boxplot / 2,
xright = tercer_cuartil,
ytop = posicion_boxplot + altura_boxplot / 2,
col = "#A7D3E8",
border = "#222222",
lwd = 1.3
)
segments(
x0 = mediana_boxplot,
y0 = posicion_boxplot - altura_boxplot / 2,
x1 = mediana_boxplot,
y1 = posicion_boxplot + altura_boxplot / 2,
lwd = 3,
col = "#111111"
)
if (length(atipicos_boxplot) > 0) {
points(
x = atipicos_boxplot,
y = rep(
posicion_boxplot,
length(atipicos_boxplot)
),
pch = 1,
col = "red",
cex = 1.1,
lwd = 1.3
)
}
media_dia <- mean(
DIA
)
mediana_dia <- median(
DIA
)
frecuencias_moda <- table(
DIA
)
frecuencia_maxima_moda <- max(
frecuencias_moda
)
modas_dia <- as.numeric(
names(
frecuencias_moda[
frecuencias_moda ==
frecuencia_maxima_moda
]
)
)
texto_moda <- paste(
modas_dia,
collapse = ", "
)
rango_texto <- paste0(
min(DIA),
" - ",
max(DIA)
)
varianza_dia <- var(
DIA
)
desviacion_dia <- sd(
DIA
)
coeficiente_variacion <- (
desviacion_dia /
media_dia
) * 100
momento_2 <- mean(
(DIA - media_dia)^2
)
momento_3 <- mean(
(DIA - media_dia)^3
)
momento_4 <- mean(
(DIA - media_dia)^4
)
asimetria_dia <- momento_3 /
momento_2^(3 / 2)
curtosis_dia <- (
momento_4 /
momento_2^2
) - 3
valores_atipicos <- boxplot.stats(
DIA
)$out
cantidad_atipicos <- length(
valores_atipicos
)
texto_valores_atipicos <- if (
cantidad_atipicos == 0
) {
"No existen"
} else {
paste0(
cantidad_atipicos,
" valores entre ",
min(valores_atipicos),
" y ",
max(valores_atipicos)
)
}
interpretacion_cv <- ifelse(
coeficiente_variacion <= 30,
"homogeneos",
"heterogeneos"
)
interpretacion_asimetria <- ifelse(
asimetria_dia > 0.10,
"asimetria positiva hacia la derecha",
ifelse(
asimetria_dia < -0.10,
"asimetria negativa hacia la izquierda",
"distribucion aproximadamente simetrica"
)
)
interpretacion_curtosis <- ifelse(
curtosis_dia > 0.10,
"leptocurtica",
ifelse(
curtosis_dia < -0.10,
"platicurtica",
"mesocurtica"
)
)
clase_modal <- which.max(
ni_agrupada
)
centro_intervalo_modal <- marcas_clase[
clase_modal
]
tercio_1 <- limite_inicial +
rango_real / 3
tercio_2 <- limite_inicial +
2 * rango_real / 3
parte_variable <- ifelse(
centro_intervalo_modal <= tercio_1,
"parte baja",
ifelse(
centro_intervalo_modal <= tercio_2,
"parte media",
"parte alta"
)
)
intervalo_modal_texto <- intervalos_texto[
clase_modal
]
tabla_indicadores <- data.frame(
Medida = c(
"Media",
"Mediana",
"Moda",
"Rango",
"Varianza",
"Desviacion estandar",
"Coeficiente de variacion (%)",
"Asimetria",
"Curtosis",
"Valores atipicos"
),
Valor = c(
round(media_dia, 2),
round(mediana_dia, 2),
texto_moda,
rango_texto,
round(varianza_dia, 2),
round(desviacion_dia, 2),
round(coeficiente_variacion, 2),
round(asimetria_dia, 2),
round(curtosis_dia, 2),
texto_valores_atipicos
)
)
knitr::kable(
tabla_indicadores,
col.names = c(
"Medida",
"Valor"
),
caption = "Tabla Nro. 3. Indicadores estadisticos de la variable DIA"
)
| Medida | Valor |
|---|---|
| Media | 15.53 |
| Mediana | 16 |
| Moda | 6 |
| Rango | 1 - 31 |
| Varianza | 73.03 |
| Desviacion estandar | 8.55 |
| Coeficiente de variacion (%) | 55.04 |
| Asimetria | 0.03 |
| Curtosis | -1.13 |
| Valores atipicos | No existen |
La variable dia de ocurrencia fluctua entre 1 y 31 dias, y sus valores giran alrededor de un promedio de 15.53 dias, con una desviacion estandar de 8.55 dias. De acuerdo con el coeficiente de variacion, los datos son heterogeneos. La mayor presencia de registros se encuentra en el intervalo [14.97 ; 17.03), ubicado en la parte media de la variable. La distribucion presenta distribucion aproximadamente simetrica y una forma platicurtica, sin presencia de valores atipicos. Este comportamiento no se considera beneficioso ni perjudicial por si mismo, pero permite identificar la concentracion temporal de los deslizamientos dentro del mes.