Justificación de la variable

La “Fecha de reinicio” representa el momento en que un sistema o infraestructura vuelve a estar operativo tras un incidente y se clasifica como una variable cuantitativa discreta, ya que para su análisis se registra en unidades de tiempo enteras y predefinidas, sin fraccionarse infinitamente. El análisis de esta variable es fundamental porque, al cruzarla con el momento del fallo, permite calcular la duración total de la inactividad y evaluar de forma objetiva la eficiencia de los equipos de respuesta.

1 Cargar datos

En esta fase, se extraen los registros de la columna Restart Date del archivo “database-1.csv”. Se realiza una limpieza exhaustiva eliminando celdas vacías y valores no numéricos, transformando los datos crudos a un formato temporal estándar (POSIXct) para permitir cálculos matemáticos precisos sobre la línea del tiempo.

database <- read.csv("database-_1_.csv", header = TRUE, sep = ",", dec = ".", check.names = FALSE)
raw_dates <- database$`Restart Date/Time`
raw_dates <- raw_dates[raw_dates != ""]
raw_dates <- na.omit(raw_dates)

# Transformación a formato fecha y hora
fechas_obj <- as.POSIXct(raw_dates, format = "%m/%d/%Y")
amperaje <- as.numeric(fechas_obj) # Usamos 'amperaje' como nombre de vector para mantener consistencia con tu código
amperaje <- na.omit(amperaje)
fechas_obj <- fechas_obj[!is.na(amperaje)]

2 Tabla de Frecuencia

Se procede a la discretización de la variable continua mediante la regla de Sturges para determinar el número óptimo de intervalos. Esta tabla organiza cronológicamente los reinicios, permitiendo observar la distribución de frecuencias absolutas y acumuladas a lo largo de los años de registro.

k <- 1 + (3.322 * log10(length(amperaje)))
k <- floor(k)

min_val <- min(amperaje)
max_val <- max(amperaje)
R <- max_val - min_val
A <- R / k

Li_num <- seq(from = min_val, to = max_val - A, by = A)
if(length(Li_num) < k) { Li_num <- c(Li_num, Li_num[length(Li_num)] + A) }
if(max(Li_num) + A < max_val) { Li_num <- c(Li_num, tail(Li_num, 1) + A) }

Ls_num <- Li_num + A
MC_num <- (Li_num + Ls_num) / 2

ni <- numeric(length(Li_num))
for (i in 1:length(Li_num)) {
  if (i == length(Li_num)) {
     ni[i] <- sum(amperaje >= Li_num[i] & amperaje <= (max_val + 100000))
  } else {
     ni[i] <- sum(amperaje >= Li_num[i] & amperaje < Ls_num[i]) 
  }
}

hi <- ni / sum(ni) * 100
Niasc <- cumsum(ni)
Nidsc <- rev(cumsum(rev(ni)))
Hiasc <- round(cumsum(hi), 2)
Hidsc <- round(rev(cumsum(rev(hi))), 2)

Li_fecha <- format(structure(Li_num, class = c("POSIXct", "POSIXt")), "%m/%d/%Y")
Ls_fecha <- format(structure(Ls_num, class = c("POSIXct", "POSIXt")), "%m/%d/%Y")
MC_fecha <- format(structure(MC_num, class = c("POSIXct", "POSIXt")), "%m/%d/%Y")

TDFAmperaje <- data.frame(Li_fecha, Ls_fecha, MC_fecha, ni, hi, Niasc, Nidsc, Hiasc, Hidsc)

tabla1_sturges <- TDFAmperaje %>%
  gt() %>%
  tab_header(
    title = md("Tabla 1: Distribución de Frecuencias"),
    subtitle = md("**Variable: Restart Date**")
  ) %>%
  cols_label(
    Li_fecha = "Desde",
    Ls_fecha = "Hasta",
    MC_fecha = "Marca Clase",
    ni = "Frec. Abs.",
    hi = "Frec. Rel. %",
    Niasc = "Ni Asc.",
    Nidsc = "Ni Desc.",
    Hiasc = "Hi Asc. %",
    Hidsc = "Hi Desc. %"
  ) %>%
  fmt_number(columns = c(hi, Hiasc, Hidsc), decimals = 2, pattern = "{x}%")

tabla1_sturges
Tabla 1: Distribución de Frecuencias
Variable: Restart Date
Desde Hasta Marca Clase Frec. Abs. Frec. Rel. % Ni Asc. Ni Desc. Hi Asc. % Hi Desc. %
01/11/2010 08/31/2010 05/07/2010 97 7.23% 97 1341 7.23% 100.00%
08/31/2010 04/20/2011 12/25/2010 95 7.08% 192 1244 14.32% 92.77%
04/20/2011 12/08/2011 08/14/2011 99 7.38% 291 1149 21.70% 85.68%
12/08/2011 07/27/2012 04/02/2012 96 7.16% 387 1050 28.86% 78.30%
07/27/2012 03/16/2013 11/20/2012 134 9.99% 521 954 38.85% 71.14%
03/16/2013 11/03/2013 07/10/2013 120 8.95% 641 820 47.80% 61.15%
11/03/2013 06/23/2014 02/27/2014 130 9.69% 771 700 57.49% 52.20%
06/23/2014 02/10/2015 10/17/2014 131 9.77% 902 570 67.26% 42.51%
02/10/2015 09/30/2015 06/06/2015 172 12.83% 1074 439 80.09% 32.74%
09/30/2015 05/19/2016 01/24/2016 138 10.29% 1212 267 90.38% 19.91%
05/19/2016 01/06/2017 09/12/2016 129 9.62% 1341 129 100.00% 9.62%

3 Histograma de Cantidad Absoluta

Esta gráfica proyecta el volumen total de reinicios ocurridos durante todo el histórico. Permite identificar de manera macroscópica si existen picos de actividad operativa o si el restablecimiento de los sistemas se mantiene constante a través del tiempo.

total_reinicios <- sum(TDFAmperaje$ni)

p_ni <- ggplot(TDFAmperaje, aes(x = MC_num, y = ni)) +
  geom_col(fill = "steelblue", color = "black", alpha = 0.8, width = A, linewidth = 0.5) +
  scale_x_continuous(labels = function(x) format(as.POSIXct(x, origin="1970-01-01"), "%d/%m/%Y"),
                     breaks = MC_num) +
  # Ajuste del límite en el eje Y hasta 2795
  scale_y_continuous(limits = c(0, 1500), 
                     expand = expansion(mult = c(0, 0.05))) +
  labs(title = "Gráfica No 1: Distribución de los Reinicios Globales",
       x = "Fecha",
       y = "Cantidad") +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 13),
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black")
  )

print(p_ni)

4 Histograma de Cantidad Absoluta

Al observar el comportamiento local, se analizan los intervalos específicos de mayor frecuencia. Esta visualización ayuda a detectar periodos de “core operativo” donde la frecuencia de reinicios es más alta, facilitando la planificación de recursos humanos y técnicos.

p_ni_local_barras <- ggplot(TDFAmperaje, aes(x = MC_num, y = ni)) +
  geom_col(fill = "steelblue", color = "black", alpha = 0.8, width = A, linewidth = 0.5) +
  scale_x_continuous(labels = function(x) format(as.POSIXct(x, origin="1970-01-01"), "%d/%m/%Y"),
                     breaks = MC_num) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.05))) +
  labs(title = "Gráfica No 2: Distribución de reinicio local",
       x = "Fecha",
       y = "Cantidad") +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 13),
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black")
  )

print(p_ni_local_barras)

5 Histograma de Cantidad Relativa

La normalización de los datos mediante porcentajes permite evaluar la probabilidad empírica de ocurrencia. Esta gráfica muestra qué proporción del total de reinicios pertenece a cada periodo temporal, eliminando el sesgo del conteo bruto.

p_hi <- ggplot(TDFAmperaje, aes(x = MC_num, y = hi)) +
  geom_col(fill = "steelblue", color = "black", alpha = 0.8, width = A, linewidth = 0.5) +
  scale_x_continuous(labels = function(x) format(as.POSIXct(x, origin="1970-01-01"), "%d/%m/%Y"),
                     breaks = MC_num) +
  scale_y_continuous(expand = expansion(mult = c(0, 0.05)),
                     labels = function(x) paste0(x, "%")) + 
  labs(title = "Gráfica No 3: Distribución Porcentual de reinicio global",
       x = "Fecha",
       y = "Porcentaje") +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 13),
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black")
  )

print(p_hi)

6 Histograma de Cantidad Relativa

Esta representación focaliza el análisis porcentual en los sub-periodos, permitiendo verificar si la intensidad de los reinicios es proporcional a lo largo del sexenio o si existen anomalías temporales donde el porcentaje de recuperación se acelera.

p_hi_barras <- ggplot(TDFAmperaje, aes(x = MC_num, y = hi)) +
  geom_col(fill = "steelblue", color = "black", alpha = 0.8, width = A, linewidth = 0.5) +
  scale_x_continuous(labels = function(x) format(as.POSIXct(x, origin="1970-01-01"), "%d/%m/%Y"),
                     breaks = MC_num) +
  scale_y_continuous(labels = function(x) paste0(x, "%"),
                     expand = expansion(mult = c(0, 0.05))) +
  labs(title = "Gráfica 4: Distribución Porcentual de reinicio local",
       x = "Fecha",
       y = "Porcentaje") +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 13),
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black")
  )

print(p_hi_barras)

7 Ojivas Combinadas de la Cantidad Absoluta Acumulada

El análisis de las ojivas permite determinar el punto exacto del tiempo donde se alcanza la mediana de los datos (la intersección entre la curva ascendente y descendente). Visualiza cómo se van completando los reinicios totales a medida que transcurre el calendario.

p_ojiva_replicada <- ggplot() +
  geom_line(data = TDFAmperaje, aes(x = Ls_num, y = Niasc, color = "Ascendente", linetype = "Ascendente"), linewidth = 0.8) +
  geom_point(data = TDFAmperaje, aes(x = Ls_num, y = Niasc, color = "Ascendente"), size = 2) +
  geom_line(data = TDFAmperaje, aes(x = Li_num, y = Nidsc, color = "Descendente", linetype = "Descendente"), linewidth = 0.8) +
  geom_point(data = TDFAmperaje, aes(x = Li_num, y = Nidsc, color = "Descendente"), size = 2) +
  scale_x_continuous(labels = function(x) format(as.POSIXct(x, origin="1970-01-01"), "%Y"), 
                     breaks = pretty_breaks(n = 5)) +
  scale_color_manual(name = NULL, 
                     values = c("Ascendente" = "black", "Descendente" = "steelblue")) +
  scale_linetype_manual(name = NULL, 
                        values = c("Ascendente" = "longdash", "Descendente" = "solid")) +
  labs(title = "Gráfica No 5: Identificación gráfica de percentiles de reinicio",
       x = "Fecha",
       y = "Cantidad") +
  theme_bw() + 
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
    legend.position = c(0.85, 0.85),
    legend.background = element_rect(color = "black", fill = "white", linewidth = 0.5)
  )

print(p_ojiva_replicada)

8 Ojivas Combinadas de la Cantidad Relativa Acumulada

Representa la probabilidad acumulada. Es fundamental para auditorías operativas, ya que permite identificar rápidamente en qué fecha se había completado, por ejemplo, el 80% de los reinicios del sistema tras los accidentes registrados.

p_ojiva_Hi <- ggplot() +
  geom_line(data = TDFAmperaje, aes(x = Ls_num, y = Hiasc, color = "Ascendente"), linewidth = 0.8) +
  geom_point(data = TDFAmperaje, aes(x = Ls_num, y = Hiasc, color = "Ascendente"), size = 2) +
  geom_line(data = TDFAmperaje, aes(x = Li_num, y = Hidsc, color = "Descendente"), linewidth = 0.8) +
  geom_point(data = TDFAmperaje, aes(x = Li_num, y = Hidsc, color = "Descendente"), size = 2) +
  scale_x_continuous(labels = function(x) format(as.POSIXct(x, origin="1970-01-01"), "%d/%m/%Y")) +
  scale_y_continuous(limits = c(0, 100),
                     labels = function(x) paste0(x, "%"),
                     expand = expansion(mult = c(0, 0.05))) +
  scale_color_manual(name = "Tipo de Ojiva", 
                     values = c("Ascendente" = "steelblue", "Descendente" = "blue")) +
  labs(title = "Gráfica No 6: Curva de probabilidad acumulada del tiempo de reinicio",
       x = "Fecha",
       y = "Porcentaje") +
  theme_classic() +
  theme(
    plot.title = element_text(hjust = 0.5, face = "bold", size = 13),
    axis.text.x = element_text(angle = 45, hjust = 1, color = "black"),
    legend.position = "bottom"
  )

print(p_ojiva_Hi)

9 Diagrama de caja

El diagrama de caja o boxplot ofrece una vista resumida de la dispersión de los reinicios. Permite identificar visualmente el rango intercuartílico (donde ocurre el 50% de los reinicios) y observar si el proceso de restablecimiento está sesgado hacia fechas tempranas o tardías.

boxplot(fechas_obj, 
        horizontal = TRUE, 
        col = "steelblue",            
        main = "Gráfica No 7: Distribución del Tiempo de Reinicio",
        xlab = "Cronología",
        xaxt = "n")                
axis.POSIXct(1, x = fechas_obj, format = "%Y", las = 1)
grid(nx = NULL, ny = NA, col = "lightgray", lty = "dotted")

10 Tabla Estadístico

A continuación se presentan los estimadores de tendencia central y de forma. Estos valores permiten caracterizar matemáticamente el comportamiento del “río del tiempo” para la variable de reinicio, midiendo su simetría y el grado de concentración de los datos.

library(knitr)
# Asegúrate de cargar también la librería 'moments' o 'e1071' si usas skewness() y kurtosis()
# library(moments) 

fechas_num <- as.numeric(fechas_obj)

# 1. Rango
ri <- min(fechas_obj)
rs <- max(fechas_obj)

# 2. Mediana y Media
mediana <- median(fechas_obj)
media_aritmetica <- mean(fechas_obj)

# 3. Moda
t <- table(fechas_obj)
Mo <- as.POSIXct(names(t)[which.max(t)], format="%Y-%m-%d") 

# 4. Dispersión
desviacion_estandar_seg <- sd(fechas_num)
desviacion_estandar_dias <- desviacion_estandar_seg / 86400
coeficiente_variabilidad <- (desviacion_estandar_seg / mean(fechas_num)) * 100

# 5. Forma
As <- skewness(fechas_num)
curtosis_val <- kurtosis(fechas_num)
Variable <- "Restart Date"

S_texto <- paste(round(desviacion_estandar_dias, 0), "días")

Tabla_indicadores <- data.frame(
  Variable,
  format(ri, "%Y-%m-%d"),
  format(rs, "%Y-%m-%d"),
  format(media_aritmetica, "%Y-%m-%d"),
  format(mediana, "%Y-%m-%d"),
  format(Mo, "%Y-%m-%d"),
  S_texto,
  round(coeficiente_variabilidad, 2), 
  round(As, 2), 
  round(curtosis_val, 2)
)

colnames(Tabla_indicadores) <- c("Variable","Mínimo","Máximo","x","Me","Mo","S","Cv (%)","As","K")

kable(Tabla_indicadores, format = "markdown", caption = "Tabla No. 1: Indicadores estadísticos de la variable Restart Date")
Tabla No. 1: Indicadores estadísticos de la variable Restart Date
Variable Mínimo Máximo x Me Mo S Cv (%) As K
Restart Date 2010-01-11 2017-01-06 2013-10-25 2014-01-01 2014-09-26 715 días 4.47 -0.22 -1.1

11 Valores atipicos

Se aplica el criterio analítico para detectar reinicios anómalos que ocurren fuera del comportamiento estándar del sistema. Estos puntos representan eventos donde el tiempo de reinicio fue excepcionalmente temprano o tardío en comparación con el resto de la muestra.

stats_outliers <- boxplot.stats(fechas_num)$out
num_outliers <- length(stats_outliers)

minimooutliers <- if(num_outliers > 0) min(stats_outliers) else NA
maximooutliers <- if(num_outliers > 0) max(stats_outliers) else NA

minimooutliers_fecha <- if(!is.na(minimooutliers)) format(as.POSIXct(minimooutliers, origin="1970-01-01"), "%Y-%m-%d") else "Ninguno"
maximooutliers_fecha <- if(!is.na(maximooutliers)) format(as.POSIXct(maximooutliers, origin="1970-01-01"), "%Y-%m-%d") else "Ninguno"

cat("Número de valores atípicos detectados:", num_outliers, "\n")
## Número de valores atípicos detectados: 0
cat("Fecha del outlier inferior:", minimooutliers_fecha, "\n")
## Fecha del outlier inferior: Ninguno
cat("Fecha del outlier superior:", maximooutliers_fecha, "\n")
## Fecha del outlier superior: Ninguno

12 Conclusión

El análisis temporal de los reinicios (2010-2017) muestra una distribución platicúrtica (curtosis = -1.1) con una asimetría negativa ligera (-0.22), indicando que los eventos de restablecimiento de sistemas ocurren de forma bastante distribuida a lo largo del periodo, con una frecuencia ligeramente superior hacia el final del sexenio. La alta desviación estándar (\(\sigma \approx 715\) días) refleja la gran variabilidad en los tiempos de respuesta operativa. Al no detectarse valores atípicos bajo el criterio del rango intercuartílico, se concluye que el proceso de reinicio, aunque variable, sigue una estructura operativa estable sin incidentes de recuperación que se consideren estadísticamente fuera de lo común.