Primero, cargamos las librerías necesarias para la limpieza de datos y el cálculo de estadísticos descriptivos.
library(dplyr)
library(janitor)
library(moments)
library(knitr) # Añadida para imprimir tablas bonitas en Markdown
Cargamos el archivo CSV y procesamos la columna de fechas para extraer únicamente el año utilizando expresiones regulares.
datos <- read.csv("C:/Users/Martin/Desktop/Estadistica/CMDB_Data.csv",
header = TRUE, sep = ";", dec = ".", fileEncoding = "latin1")
# Limpiamos los nombres de las columnas
df <- clean_names(datos)
# Usamos la columna 'x0' (donde R guardó la fecha) y la convertimos a texto
fechas_texto <- as.character(df$x0)
# Extraemos el año usando expresiones regulares (busca 4 dígitos seguidos)
year_texto <- gsub(".*?([0-9]{4}).*", "\\1", fechas_texto)
# Convertimos a número y eliminamos los valores vacíos (NA)
anio <- suppressWarnings(as.numeric(year_texto))
PrimerAnio <- na.omit(anio)
Calculamos las frecuencias absolutas (ni), relativas
porcentuales (hi_porc) y sus respectivos acumulados,
agregando una fila de totales al final.
TDFPrimerAnio <- table(PrimerAnio)
TablaPrimerAnio <- as.data.frame(TDFPrimerAnio)
names(TablaPrimerAnio) <- c("Año", "Freq")
# Cálculo de frecuencias simples y acumuladas
ni <- TablaPrimerAnio$Freq
hi_porc <- (ni / sum(ni)) * 100
Ni_asc <- cumsum(ni)
Hi_asc <- cumsum(hi_porc)
Ni_dsc <- rev(cumsum(rev(ni)))
Hi_dsc <- rev(cumsum(rev(hi_porc)))
# Crear la Tabla principal
TablaPrimerAnioFinal <- data.frame(
Año = as.character(TablaPrimerAnio$Año),
ni = ni,
hi_porc = round(hi_porc, 2),
Ni_asc = Ni_asc,
Hi_asc = round(Hi_asc, 2),
Ni_dsc = Ni_dsc,
Hi_dsc = round(Hi_dsc, 2)
)
# Agregar Fila de Totales
Fila_Total <- data.frame(
Año = "TOTAL",
ni = sum(TablaPrimerAnioFinal$ni),
hi_porc = round(sum(TablaPrimerAnioFinal$hi_porc), 0),
Ni_asc = NA,
Hi_asc = NA,
Ni_dsc = NA,
Hi_dsc = NA
)
# Unir tabla con el total
TablaFinal_Con_Totales <- rbind(TablaPrimerAnioFinal, Fila_Total)
# Mostrar la tabla formateada
kable(TablaFinal_Con_Totales, caption = "Tabla de Frecuencias (Año por Año)")
| Año | ni | hi_porc | Ni_asc | Hi_asc | Ni_dsc | Hi_dsc |
|---|---|---|---|---|---|---|
| 2011 | 32 | 2.34 | 32 | 2.34 | 1366 | 100.00 |
| 2012 | 25 | 1.83 | 57 | 4.17 | 1334 | 97.66 |
| 2013 | 462 | 33.82 | 519 | 37.99 | 1309 | 95.83 |
| 2014 | 89 | 6.52 | 608 | 44.51 | 847 | 62.01 |
| 2015 | 162 | 11.86 | 770 | 56.37 | 758 | 55.49 |
| 2017 | 596 | 43.63 | 1366 | 100.00 | 596 | 43.63 |
| TOTAL | 1366 | 100.00 | NA | NA | NA | NA |
A continuación se presentan las distribuciones de envíos por año en valores absolutos y porcentuales.
# Calculamos un límite superior dinámico (1.2 significa un 20% más alto que el máximo real)
limite_max_y <- max(TablaPrimerAnioFinal$ni, na.rm = TRUE) * 1.2
# Gráfico 1 modificado
barplot(TablaPrimerAnioFinal$ni,
main = "Gráfico No.1: Distribución de cantidad por año",
xlab = "Año", ylab = "Cantidad",
col = "orange",
names.arg = TablaPrimerAnioFinal$Año,
ylim = c(0, limite_max_y), # <-- Aquí agregamos el límite del eje Y
las = 2, cex.names = 0.8, cex.axis = 0.8)
# Gráfico 2
barplot(TablaPrimerAnioFinal$ni,
main = "Gráfico No.2: Distribución por año (Escala Total)",
xlab = "Año", ylab = "Cantidad",
col = "red",
names.arg = TablaPrimerAnioFinal$Año,
ylim = c(0, max(PrimerAnio)),
las = 2, cex.names = 0.8, cex.axis = 0.8)
# Calculamos un límite superior dinámico (20% más alto que el porcentaje máximo)
limite_max_y_porc <- max(TablaPrimerAnioFinal$hi_porc, na.rm = TRUE) * 1.2
# Gráfico 3 modificado
barplot(TablaPrimerAnioFinal$hi_porc,
main = "Gráfico No.3: Distribución porcentual por año",
xlab = "Año", ylab = "Porcentaje (%)",
col = "skyblue",
names.arg = TablaPrimerAnioFinal$Año,
ylim = c(0, limite_max_y_porc), # <-- Aquí agregamos el límite del eje Y
las = 2, cex.names = 0.8, cex.axis = 0.8)
# Gráfico 4
barplot(TablaPrimerAnioFinal$hi_porc,
main = "Gráfico No.4: Distribución porcentual (Escala 100%)",
xlab = "Año", ylab = "Porcentaje (%)",
col = "blue",
names.arg = TablaPrimerAnioFinal$Año,
ylim = c(0, 100),
las = 2, cex.names = 0.8, cex.axis = 0.8)
x <- as.numeric(TablaPrimerAnioFinal$Año)
# Gráficos combinados
limite_max_y <- max(TablaPrimerAnioFinal$Ni_asc)
plot(x, TablaPrimerAnioFinal$Ni_asc, type = "b", pch=19,
main = "Gráfico No.9: Ojivas Ni: ascendente vs descendente",
xlab = "Año", ylab = "Frecuencia acumulada", col = "green",
ylim = c(0, limite_max_y),
xaxt = "n") # <-- Apaga el eje X automático
lines(x, TablaPrimerAnioFinal$Ni_dsc, type = "b", pch=19, col = "blue")
axis(1, at = x, labels = x, las = 2)
plot(x, TablaPrimerAnioFinal$Hi_asc, type = "b", pch=19,
main = "Gráfico No.10: Ojivas Hi (%): ascendente vs descendente",
xlab = "Año", ylab = "% acumulado", col = "green",
ylim = c(0, 100),
xaxt = "n") # <-- Apaga el eje X automático
lines(x, TablaPrimerAnioFinal$Hi_dsc, type = "b", pch=19, col = "blue")
axis(1, at = x, labels = x, las = 2)
Resumen estadístico de los datos analizados.
cuartiles <- quantile(PrimerAnio, probs = c(0.25, 0.5, 0.75))
media <- mean(PrimerAnio)
desviacion <- sd(PrimerAnio)
valores <- c(min(PrimerAnio), max(PrimerAnio), max(PrimerAnio) - min(PrimerAnio),
media, median(PrimerAnio), cuartiles[1], cuartiles[3], var(PrimerAnio),
desviacion, (desviacion / media * 100), skewness(PrimerAnio), kurtosis(PrimerAnio))
nombres <- c("Mínimo", "Máximo", "Rango", "Media", "Mediana", "Q1", "Q3",
"Varianza", "Desv. estándar", "Coef. de variación (%)", "Asimetría", "Curtosis")
tabla_horizontal <- as.data.frame(t(valores))
colnames(tabla_horizontal) <- nombres
kable(tabla_horizontal, caption = "Medidas Estadísticas de los Años de Envío")
| Mínimo | Máximo | Rango | Media | Mediana | Q1 | Q3 | Varianza | Desv. estándar | Coef. de variación (%) | Asimetría | Curtosis |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 2011 | 2017 | 6 | 2014.982 | 2015 | 2013 | 2017 | 3.705186 | 1.924886 | 0.0955287 | -0.1514037 | 1.448347 |
Identificación de valores atípicos mediante el método del Rango Intercuartílico (IQR).
IQR_val <- cuartiles[3] - cuartiles[1]
limite_inferior <- cuartiles[1] - 1.5 * IQR_val
limite_superior <- cuartiles[3] + 1.5 * IQR_val
outliers <- PrimerAnio[PrimerAnio < limite_inferior | PrimerAnio > limite_superior]
num_outliers <- length(outliers)
Tabla_outliers <- data.frame(
"Cantidad_outliers" = num_outliers,
"Valor_mínimo_atípico" = if (num_outliers > 0) min(outliers) else NA,
"Valor_máximo_atípico" = if (num_outliers > 0) max(outliers) else NA
)
kable(Tabla_outliers, caption = "Análisis de Outliers")
| Cantidad_outliers | Valor_mínimo_atípico | Valor_máximo_atípico |
|---|---|---|
| 0 | NA | NA |
CONCLUSIÓN DE LA VARIABLE Date_submite Concentración principal: La distribución temporal presenta un comportamiento bimodal o altamente concentrado en dos periodos específicos. El año 2017 registra la mayor frecuencia absoluta con 596 muestras (representando el 43.6% del total), seguido por el año 2013 con 462 muestras (33.8%). Estos dos años en conjunto agrupan más de tres cuartas partes (77.4%) del volumen total de datos.