Justificación de la variable
La “Fecha y hora de reinicio” representa el momento exacto en que la infraestructura o el sistema vuelve a estar operativo tras un incidente. Es una variable cuantitativa continua debido a la naturaleza fluida del tiempo; no se mide en pasos discretos, sino que puede dividirse en fracciones infinitesimales (segundos, milisegundos). Su análisis es crucial para determinar la eficiencia de la respuesta operativa y modelar la duración de las interrupciones, permitiendo identificar patrones estacionales o tendencias en la recuperación de los sistemas industriales.
En esta fase, se extraen los registros de la columna Restart Date/Time 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 %H:%M")
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)]
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 %H:%M")
Ls_fecha <- format(structure(Ls_num, class = c("POSIXct", "POSIXt")), "%m/%d/%Y %H:%M")
MC_fecha <- format(structure(MC_num, class = c("POSIXct", "POSIXt")), "%m/%d/%Y %H:%M")
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/Time**")
) %>%
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/Time | ||||||||
| Desde | Hasta | Marca Clase | Frec. Abs. | Frec. Rel. % | Ni Asc. | Ni Desc. | Hi Asc. % | Hi Desc. % |
|---|---|---|---|---|---|---|---|---|
| 01/11/2010 22:08 | 08/31/2010 21:41 | 05/07/2010 21:54 | 98 | 7.31% | 98 | 1341 | 7.31% | 100.00% |
| 08/31/2010 21:41 | 04/20/2011 21:14 | 12/25/2010 21:28 | 94 | 7.01% | 192 | 1243 | 14.32% | 92.69% |
| 04/20/2011 21:14 | 12/08/2011 20:48 | 08/14/2011 21:01 | 99 | 7.38% | 291 | 1149 | 21.70% | 85.68% |
| 12/08/2011 20:48 | 07/27/2012 20:21 | 04/02/2012 20:35 | 97 | 7.23% | 388 | 1050 | 28.93% | 78.30% |
| 07/27/2012 20:21 | 03/16/2013 19:55 | 11/20/2012 20:08 | 133 | 9.92% | 521 | 953 | 38.85% | 71.07% |
| 03/16/2013 19:55 | 11/03/2013 19:28 | 07/10/2013 19:42 | 120 | 8.95% | 641 | 820 | 47.80% | 61.15% |
| 11/03/2013 19:28 | 06/23/2014 19:02 | 02/27/2014 19:15 | 131 | 9.77% | 772 | 700 | 57.57% | 52.20% |
| 06/23/2014 19:02 | 02/10/2015 18:35 | 10/17/2014 18:48 | 130 | 9.69% | 902 | 569 | 67.26% | 42.43% |
| 02/10/2015 18:35 | 09/30/2015 18:09 | 06/06/2015 18:22 | 173 | 12.90% | 1075 | 439 | 80.16% | 32.74% |
| 09/30/2015 18:09 | 05/19/2016 17:42 | 01/24/2016 17:55 | 138 | 10.29% | 1213 | 266 | 90.45% | 19.84% |
| 05/19/2016 17:42 | 01/06/2017 17:16 | 09/12/2016 17:29 | 128 | 9.55% | 1341 | 128 | 100.00% | 9.55% |
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)
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)
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)
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)
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)
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)
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")
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)
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 %H:%M")
# 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/Time"
S_texto <- paste(round(desviacion_estandar_dias, 2), "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/Time.")
| Variable | Mínimo | Máximo | x | Me | Mo | S | Cv (%) | As | K |
|---|---|---|---|---|---|---|---|---|---|
| Restart Date/Time | 2010-01-11 | 2017-01-06 | 2013-10-26 | 2014-01-01 | 2011-12-12 | 715.17 días | 4.47 | -0.22 | -1.1 |
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
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.