0. Cargar Librerías

Primero, cargamos las librerías necesarias para la limpieza de datos, el cálculo estadístico y la presentación de tablas.

library(dplyr)
library(janitor)
library(moments)
library(gt)

1. Carga y Preparación de Datos

Cargamos el archivo CSV y procesamos la columna DATE_SUBMITTE para extraer únicamente el año.

datos <- read.csv(
  "C:/Users/Martin/Desktop/Estadistica/CMDB_Data.csv",
  header = TRUE,
  sep = ";",
  dec = ".",
  fileEncoding = "UTF-8-BOM",
  check.names = FALSE
)

# Limpiar los nombres de las columnas.
df <- clean_names(datos)

# Usar la columna DATE_SUBMITTE, que contiene día, mes y año.
# Después de clean_names(), la columna queda como date_submitte.
if (!"date_submitte" %in% names(df)) {
  stop(paste0(
    "No se encontró la columna DATE_SUBMITTE. Columnas disponibles: ",
    paste(names(df), collapse = ", ")
  ))
}

fechas_texto <- trimws(as.character(df$date_submitte))

# Convertir la fecha completa a tipo Date.
fecha_submitte <- as.Date(fechas_texto, tryFormats = c(
  "%d/%m/%Y",
  "%m/%d/%Y",
  "%Y-%m-%d",
  "%Y/%m/%d",
  "%d-%m-%Y",
  "%m-%d-%Y"
))

# Extraer solo el año.
anio <- as.numeric(format(fecha_submitte, "%Y"))
PrimerAnio <- na.omit(anio)

if (length(PrimerAnio) == 0) {
  stop("No se pudieron extraer años válidos desde DATE_SUBMITTE.")
}

2. Tabla de Frecuencias

Calculamos las frecuencias absolutas, relativas porcentuales y acumuladas, agregando una fila de totales al final.

TDFPrimerAnio <- table(PrimerAnio)
TablaPrimerAnio <- as.data.frame(TDFPrimerAnio, stringsAsFactors = FALSE)

if (ncol(TablaPrimerAnio) != 2) {
  stop("La tabla de frecuencias no tiene el formato esperado. Revisa que PrimerAnio tenga datos válidos.")
}

names(TablaPrimerAnio) <- c("Anio", "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(
  Anio = as.character(TablaPrimerAnio$Anio),
  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(
  Anio = "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
)

TablaFinal_Con_Totales <- rbind(TablaPrimerAnioFinal, Fila_Total)

tabla_frecuencias_gt <- TablaFinal_Con_Totales %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 1**"),
    subtitle = md("Distribución de frecuencias por año de envío")
  ) %>%
  tab_source_note(
    source_note = md("Autores: Grupo 1")
  ) %>%
  cols_label(
    Anio = "Año",
    ni = "Frecuencia absoluta (ni)",
    hi_porc = "Frecuencia relativa (%)",
    Ni_asc = "Frecuencia acumulada ascendente",
    Hi_asc = "% acumulado ascendente",
    Ni_dsc = "Frecuencia acumulada descendente",
    Hi_dsc = "% acumulado descendente"
  ) %>%
  fmt_number(columns = c(hi_porc, Hi_asc, Hi_dsc), decimals = 2) %>%
  fmt_number(columns = c(ni, Ni_asc, Ni_dsc), decimals = 0) %>%
  sub_missing(columns = everything(), missing_text = "") %>%
  tab_style(
    style = cell_text(weight = "bold"),
    locations = cells_body(rows = Anio == "TOTAL")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

tabla_frecuencias_gt
Tabla N° 1
Distribución de frecuencias por año de envío
Año Frecuencia absoluta (ni) Frecuencia relativa (%) Frecuencia acumulada ascendente % acumulado ascendente Frecuencia acumulada descendente % acumulado descendente
2011 32 2.34 32 2.34 1,366 100.00
2012 25 1.83 57 4.17 1,334 97.66
2013 462 33.82 519 37.99 1,309 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 1,366 100.00 596 43.63
TOTAL 1,366 100.00



Autores: Grupo 1

3. Gráficos de Barras

A continuación se presentan las distribuciones de envíos por año en valores absolutos y porcentuales.

# Límite superior dinámico para la frecuencia absoluta.
limite_max_y <- max(TablaPrimerAnioFinal$ni, na.rm = TRUE) * 1.2

barplot(
  TablaPrimerAnioFinal$ni,
  main = "Gráfico N° 1: Distribución de cantidad por año",
  xlab = "Año",
  ylab = "Cantidad",
  col = "orange",
  names.arg = TablaPrimerAnioFinal$Anio,
  ylim = c(0, limite_max_y),
  las = 2,
  cex.names = 0.8,
  cex.axis = 0.8
)

barplot(
  TablaPrimerAnioFinal$ni,
  main = "Gráfico N° 2: Distribución por año en escala total",
  xlab = "Año",
  ylab = "Cantidad",
  col = "red",
  names.arg = TablaPrimerAnioFinal$Anio,
  ylim = c(0, max(TablaPrimerAnioFinal$ni, na.rm = TRUE) * 1.2),
  las = 2,
  cex.names = 0.8,
  cex.axis = 0.8
)

# Límite superior dinámico para el porcentaje.
limite_max_y_porc <- max(TablaPrimerAnioFinal$hi_porc, na.rm = TRUE) * 1.2

barplot(
  TablaPrimerAnioFinal$hi_porc,
  main = "Gráfico N° 3: Distribución porcentual por año",
  xlab = "Año",
  ylab = "Porcentaje (%)",
  col = "skyblue",
  names.arg = TablaPrimerAnioFinal$Anio,
  ylim = c(0, limite_max_y_porc),
  las = 2,
  cex.names = 0.8,
  cex.axis = 0.8
)

barplot(
  TablaPrimerAnioFinal$hi_porc,
  main = "Gráfico N° 4: Distribución porcentual en escala 100%",
  xlab = "Año",
  ylab = "Porcentaje (%)",
  col = "blue",
  names.arg = TablaPrimerAnioFinal$Anio,
  ylim = c(0, 100),
  las = 2,
  cex.names = 0.8,
  cex.axis = 0.8
)

4. Ojivas

x <- as.numeric(TablaPrimerAnioFinal$Anio)

limite_max_y <- max(TablaPrimerAnioFinal$Ni_asc, na.rm = TRUE)

plot(
  x,
  TablaPrimerAnioFinal$Ni_asc,
  type = "b",
  pch = 19,
  main = "Gráfico N° 5: Ojivas de frecuencia acumulada",
  xlab = "Año",
  ylab = "Frecuencia acumulada",
  col = "green",
  ylim = c(0, limite_max_y),
  xaxt = "n"
)
lines(x, TablaPrimerAnioFinal$Ni_dsc, type = "b", pch = 19, col = "blue")
axis(1, at = x, labels = x, las = 2)
legend(
  "topleft",
  legend = c("Ascendente", "Descendente"),
  col = c("green", "blue"),
  pch = 19,
  bty = "n"
)

plot(
  x,
  TablaPrimerAnioFinal$Hi_asc,
  type = "b",
  pch = 19,
  main = "Gráfico N° 6: Ojivas porcentuales",
  xlab = "Año",
  ylab = "% acumulado",
  col = "green",
  ylim = c(0, 100),
  xaxt = "n"
)
lines(x, TablaPrimerAnioFinal$Hi_dsc, type = "b", pch = 19, col = "blue")
axis(1, at = x, labels = x, las = 2)
legend(
  "topleft",
  legend = c("Ascendente", "Descendente"),
  col = c("green", "blue"),
  pch = 19,
  bty = "n"
)

5. Medidas Estadísticas

Resumen estadístico de los datos analizados.

cuartiles <- quantile(PrimerAnio, probs = c(0.25, 0.5, 0.75))
media <- mean(PrimerAnio)
desviacion <- sd(PrimerAnio)

tabla_estadisticas <- data.frame(
  "Mínimo" = min(PrimerAnio),
  "Máximo" = max(PrimerAnio),
  "Rango" = max(PrimerAnio) - min(PrimerAnio),
  "Media" = round(media, 2),
  "Mediana" = median(PrimerAnio),
  "Q1" = cuartiles[1],
  "Q3" = cuartiles[3],
  "Varianza" = round(var(PrimerAnio), 2),
  "Desviación estándar" = round(desviacion, 2),
  "Coeficiente de variación (%)" = round(desviacion / media * 100, 2),
  "Asimetría" = round(skewness(PrimerAnio), 2),
  "Curtosis" = round(kurtosis(PrimerAnio), 2),
  check.names = FALSE
)

tabla_estadisticas_gt <- tabla_estadisticas %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 2**"),
    subtitle = md("Medidas estadísticas de los años de envío")
  ) %>%
  tab_source_note(
    source_note = md("Autores: Grupo 1")
  ) %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

tabla_estadisticas_gt
Tabla N° 2
Medidas estadísticas de los años de envío
Mínimo Máximo Rango Media Mediana Q1 Q3 Varianza Desviación estándar Coeficiente de variación (%) Asimetría Curtosis
2011 2017 6 2014.98 2015 2013 2017 3.71 1.92 0.1 -0.15 1.45
Autores: Grupo 1

6. Detección de Outliers

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 de 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,
  check.names = FALSE
)

tabla_outliers_gt <- Tabla_outliers %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N° 3**"),
    subtitle = md("Análisis de valores atípicos")
  ) %>%
  tab_source_note(
    source_note = md("Autores: Grupo 1")
  ) %>%
  sub_missing(columns = everything(), missing_text = "No aplica") %>%
  tab_options(
    table.border.top.color = "black",
    table.border.bottom.color = "black",
    heading.border.bottom.color = "black",
    heading.border.bottom.width = px(2),
    column_labels.border.top.color = "black",
    column_labels.border.bottom.color = "black",
    column_labels.border.bottom.width = px(2),
    table_body.hlines.color = "gray",
    table_body.border.bottom.color = "black",
    row.striping.include_table_body = TRUE
  )

tabla_outliers_gt
Tabla N° 3
Análisis de valores atípicos
Cantidad de outliers Valor mínimo atípico Valor máximo atípico
0 No aplica No aplica
Autores: Grupo 1

7. Conclusión

Conclusión de la variable DATE_SUBMITTE

La distribución temporal presenta una concentración marcada en años específicos. El año 2017 registra la mayor frecuencia absoluta, seguido por el año 2013. En conjunto, estos dos años agrupan la mayor parte del volumen total de registros, lo que evidencia que la toma o registro de muestras no se distribuye de manera uniforme a lo largo del tiempo.