# Cargar los datos
datos <- read_excel("C:/Users/hp/Downloads/Producción Campo Sacha.csv.xlsx")
cat("✓ Datos cargados correctamente\n")
## ✓ Datos cargados correctamente
cat("✓ Dimensiones:", dim(datos)[1], "filas ×", dim(datos)[2], "columnas\n")
## ✓ Dimensiones: 8344 filas × 31 columnas
# Verificar y extraer la variable Voltaje
if(!"Voltaje" %in% colnames(datos)) {
col_voltaje <- grep("volt|voltage|tensión|tension|VOLT",
colnames(datos),
ignore.case = TRUE,
value = TRUE)[1]
if(!is.na(col_voltaje)) {
datos$Voltaje <- datos[[col_voltaje]]
cat("✓ Variable 'Voltaje' creada a partir de:", col_voltaje, "\n")
} else {
stop("✗ No se encontró ninguna columna relacionada con Voltaje")
}
}
# Preparar el vector de Voltaje
Voltaje <- as.numeric(datos$Voltaje)
Voltaje <- na.omit(Voltaje)
n <- length(Voltaje)
cat("\n", rep("=", 70), "\n", sep = "")
##
## ======================================================================
cat("INFORME ESTADÍSTICO - VARIABLE: VOLTAJE\n")
## INFORME ESTADÍSTICO - VARIABLE: VOLTAJE
cat(rep("=", 70), "\n\n", sep = "")
## ======================================================================
cat("• Tamaño de muestra (n):", format(n, big.mark = ","), "observaciones\n")
## • Tamaño de muestra (n): 7,704 observaciones
cat("• Rango de valores:", round(min(Voltaje), 1), "a", round(max(Voltaje), 1), "V\n")
## • Rango de valores: 0 a 847 V
cat("• Promedio:", round(mean(Voltaje), 1), "V\n")
## • Promedio: 422.5 V
cat("• Desviación estándar:", round(sd(Voltaje), 1), "V\n\n")
## • Desviación estándar: 42.7 V
# Definir número de intervalos (Regla de Sturges ajustada)
k <- min(ceiling(log2(n)) + 1, 15)
if(n > 1000) k <- 12
# Calcular estadísticas iniciales
rango <- max(Voltaje) - min(Voltaje)
media_v <- mean(Voltaje)
sd_v <- sd(Voltaje)
cv <- sd_v / media_v * 100
cat("• Número de intervalos sugerido:", k, "\n")
## • Número de intervalos sugerido: 12
cat("• Coeficiente de variación:", round(cv, 1), "%\n")
## • Coeficiente de variación: 10.1 %
# Método de construcción de intervalos
if(cv < 50 && n > 100) {
cat("• Método seleccionado: Límites basados en percentiles\n")
percentiles <- quantile(Voltaje, probs = seq(0, 1, length.out = k + 1))
lim_inf <- as.numeric(percentiles)
lim_inf[1] <- floor(lim_inf[1] / 10) * 10
lim_inf[k + 1] <- ceiling(lim_inf[k + 1] / 10) * 10
} else {
cat("• Método seleccionado: Amplitud constante\n")
amplitud <- 3.5 * sd_v / (n^(1/3))
amplitud <- round(amplitud / 5) * 5
if(amplitud < 10) amplitud <- 10
if(amplitud > 50) amplitud <- 50
cat("• Amplitud de clase:", amplitud, "V\n")
centro <- round(media_v / amplitud) * amplitud
inicio <- centro - floor(k/2) * amplitud
if(inicio > min(Voltaje)) inicio <- floor(min(Voltaje) / amplitud) * amplitud
lim_inf <- seq(from = inicio, by = amplitud, length.out = k + 1)
if(lim_inf[k + 1] < max(Voltaje)) {
lim_inf <- c(lim_inf, lim_inf[k + 1] + amplitud)
k <- k + 1
}
}
## • Método seleccionado: Límites basados en percentiles
# Crear intervalos y calcular frecuencias
intervalos <- cut(Voltaje, breaks = lim_inf, include.lowest = TRUE, right = FALSE)
frecuencia <- table(intervalos)
frecuencia_rel <- frecuencia / n
frecuencia_acum <- cumsum(frecuencia)
frecuencia_rel_acum <- cumsum(frecuencia_rel)
marca_clase_tabla <- (lim_inf[1:k] + lim_inf[2:(k+1)]) / 2
# Crear tabla de distribución de frecuencias
TDF_Voltaje <- data.frame(
Li = round(lim_inf[1:k], 1),
Ls = round(lim_inf[2:(k+1)], 1),
MC = round(marca_clase_tabla, 1),
"ni (FA)" = as.numeric(frecuencia),
"hi (FR)" = round(as.numeric(frecuencia_rel), 4),
"Ni (FAA)" = as.numeric(frecuencia_acum),
"Hi (FRA)" = round(as.numeric(frecuencia_rel_acum), 4)
)
cat("\n", rep("=", 70), "\n", sep = "")
##
## ======================================================================
cat("TABLA 1: DISTRIBUCIÓN DE FRECUENCIAS DEL VOLTAJE\n")
## TABLA 1: DISTRIBUCIÓN DE FRECUENCIAS DEL VOLTAJE
cat(rep("=", 70), "\n\n", sep = "")
## ======================================================================
print(TDF_Voltaje)
## Li Ls MC ni..FA. hi..FR. Ni..FAA. Hi..FRA.
## 1 0 368 184.0 627 0.0814 627 0.0814
## 2 368 390 379.0 646 0.0839 1273 0.1652
## 3 390 402 396.0 637 0.0827 1910 0.2479
## 4 402 411 406.5 643 0.0835 2553 0.3314
## 5 411 420 415.5 642 0.0833 3195 0.4147
## 6 420 428 424.0 653 0.0848 3848 0.4995
## 7 428 435 431.5 630 0.0818 4478 0.5813
## 8 435 440 437.5 514 0.0667 4992 0.6480
## 9 440 450 445.0 728 0.0945 5720 0.7425
## 10 450 459 454.5 629 0.0816 6349 0.8241
## 11 459 472 465.5 619 0.0803 6968 0.9045
## 12 472 850 661.0 736 0.0955 7704 1.0000
# Encontrar intervalo modal
indice_modal <- which.max(frecuencia)
indice_50 <- which(frecuencia_acum >= n/2)[1]
indice_80 <- which(frecuencia_acum >= n * 0.8)[1]
cat("\nRESUMEN DE LA DISTRIBUCIÓN:\n")
##
## RESUMEN DE LA DISTRIBUCIÓN:
cat(rep("-", 40), "\n", sep = "")
## ----------------------------------------
cat("1. INTERVALO MODAL:\n")
## 1. INTERVALO MODAL:
cat(" • Intervalo:", names(frecuencia)[indice_modal], "\n")
## • Intervalo: [472,850]
cat(" • Frecuencia absoluta:", max(frecuencia), "\n")
## • Frecuencia absoluta: 736
cat(" • Frecuencia relativa:", round(100 * max(frecuencia_rel), 1), "%\n")
## • Frecuencia relativa: 9.6 %
cat(" • Marca de clase:", round(marca_clase_tabla[indice_modal], 1), "V\n\n")
## • Marca de clase: 661 V
cat("2. DISTRIBUCIÓN DE FRECUENCIAS:\n")
## 2. DISTRIBUCIÓN DE FRECUENCIAS:
cat(" • Intervalos con datos:", sum(frecuencia > 0), "de", k, "\n")
## • Intervalos con datos: 12 de 12
cat(" • Intervalos sin datos:", sum(frecuencia == 0), "\n")
## • Intervalos sin datos: 0
cat(" • Concentración principal:",
round(100 * sum(frecuencia[1:round(k/2)]) / n, 1),
"% en la primera mitad de intervalos\n\n")
## • Concentración principal: 49.9 % en la primera mitad de intervalos
cat("3. ACUMULACIÓN DE DATOS:\n")
## 3. ACUMULACIÓN DE DATOS:
cat(" • 50% de datos acumulados en:", indice_50, "intervalos\n")
## • 50% de datos acumulados en: 7 intervalos
cat(" • Intervalo del 50%:", names(frecuencia)[indice_50], "\n")
## • Intervalo del 50%: [428,435)
cat(" • Hasta aproximadamente:", round(marca_clase_tabla[indice_50], 1), "V\n")
## • Hasta aproximadamente: 431.5 V
cat(" • 80% de datos acumulados en:", indice_80, "intervalos\n")
## • 80% de datos acumulados en: 10 intervalos
cat(" • Intervalo del 80%:", names(frecuencia)[indice_80], "\n")
## • Intervalo del 80%: [450,459)
cat(" • Hasta aproximadamente:", round(marca_clase_tabla[indice_80], 1), "V\n")
## • Hasta aproximadamente: 454.5 V
cat("\n", rep("-", 70), "\n\n", sep = "")
##
## ----------------------------------------------------------------------
# Preparar variables para las gráficas
frec_acum <- as.numeric(frecuencia_acum)
marca_clase <- marca_clase_tabla
cat("✓ Variables preparadas para gráficas:\n")
## ✓ Variables preparadas para gráficas:
cat(" • Voltaje:", n, "observaciones\n")
## • Voltaje: 7704 observaciones
cat(" • Marcas de clase:", length(marca_clase), "intervalos\n")
## • Marcas de clase: 12 intervalos
cat(" • Límites de intervalos:", length(lim_inf), "puntos\n")
## • Límites de intervalos: 13 puntos
# Gráfica 1: Histograma
hist(Voltaje,
breaks = lim_inf,
col = "#1E88E5",
border = "white",
main = "Histograma de distribución de voltaje",
xlab = "Voltaje (V)",
ylab = "cantidad",
las = 1,
cex.main = 1.1)
# Agregar línea de densidad
lines(density(Voltaje), col = "#FF5722", lwd = 2)
# Agregar líneas de media y mediana
abline(v = mean(Voltaje), col = "#4CAF50", lwd = 2, lty = 2)
abline(v = median(Voltaje), col = "#2196F3", lwd = 2, lty = 3)
# Leyenda
legend("topright",
legend = c("Densidad", "Media", "Mediana"),
col = c("#FF5722", "#4CAF50", "#2196F3"),
lwd = 2, lty = c(1, 2, 3),
cex = 0.8)
Figura 1: Histograma de distribución de voltaje
# Gráfica 2: Diagrama de caja
boxplot(Voltaje,
horizontal = TRUE,
col = "#FFC107",
border = "#FF9800",
main = "Diagrama de caja y bigotes",
xlab = "Voltaje (V)",
las = 1,
cex.main = 1.1)
# Agregar estadísticas
estad_box <- boxplot.stats(Voltaje)$stats
text(estad_box[3], 1.3,
paste("Mediana:", round(estad_box[3], 1), "V"),
col = "#388E3C",
cex = 0.9,
font = 2)
# Mostrar valores atípicos si existen
outliers <- boxplot.stats(Voltaje)$out
if(length(outliers) > 0) {
points(outliers, rep(1, length(outliers)),
col = "#D32F2F",
pch = 4,
cex = 1)
text(mean(outliers), 0.8,
paste("Atípicos:", length(outliers)),
col = "#D32F2F",
cex = 0.8,
font = 2)
}
# Agregar líneas para cuartiles
abline(v = estad_box[2], col = "#757575", lty = 3, lwd = 1)
abline(v = estad_box[4], col = "#757575", lty = 3, lwd = 1)
Figura 2: Diagrama de caja y bigotes
# Gráfica 3: Distribución por cuartiles
categorias <- cut(Voltaje,
breaks = quantile(Voltaje, probs = seq(0, 1, 0.25)),
include.lowest = TRUE,
labels = c("Q1 (0-25%)", "Q2 (25-50%)", "Q3 (50-75%)", "Q4 (75-100%)"))
frec_cat <- table(categorias)
colores_bar <- hcl.colors(length(frec_cat), "BluYl")
bar_pos <- barplot(frec_cat,
col = colores_bar,
border = "black",
main = "Distribución por cuartiles",
xlab = "Cuartiles",
ylab = "cantidad",
las = 1,
cex.main = 1.1,
ylim = c(0, max(frec_cat) * 1.2))
# Agregar valores en las barras
text(bar_pos,
frec_cat,
labels = paste0(frec_cat, "\n(", round(100 * frec_cat/sum(frec_cat), 1), "%)"),
pos = 3,
cex = 0.8,
col = "black",
font = 2)
# Agregar línea de promedio
abline(h = n/4, col = "#616161", lty = 2, lwd = 1.5)
text(max(bar_pos) * 0.8, n/4,
paste("Promedio por cuartil:", round(n/4, 0)),
col = "#616161",
cex = 0.7,
pos = 3)
Figura 3: Distribución por cuartiles
# Gráfica 4: Ojiva de frecuencias acumuladas
plot(marca_clase, frec_acum,
type = "b",
pch = 19,
col = "#004D40",
lwd = 2,
main = "Ojiva de frecuencias acumuladas",
xlab = "Marca de Clase (V)",
ylab = "Frecuencia Acumulada",
las = 1,
cex.main = 1.1,
ylim = c(0, n * 1.05))
grid(col = "gray90", lty = "dotted")
# Agregar líneas de percentiles
abline(h = n/2, col = "#FF5722", lty = 2, lwd = 1.5)
abline(h = n * 0.8, col = "#2196F3", lty = 2, lwd = 1.5)
abline(h = n, col = "#9C27B0", lty = 2, lwd = 1.5)
# Agregar etiquetas
text(max(marca_clase) * 0.7, n/2,
paste("50% (", round(n/2, 0), " obs.)", sep = ""),
col = "#FF5722",
cex = 0.8,
pos = 3,
font = 2)
text(max(marca_clase) * 0.7, n * 0.8,
paste("80% (", round(n * 0.8, 0), " obs.)", sep = ""),
col = "#2196F3",
cex = 0.8,
pos = 3,
font = 2)
text(max(marca_clase) * 0.7, n,
paste("100% (", n, " obs.)", sep = ""),
col = "#9C27B0",
cex = 0.8,
pos = 3,
font = 2)
# Agregar puntos importantes
points(marca_clase[indice_50], frec_acum[indice_50],
col = "#FF5722", pch = 17, cex = 1.5)
points(marca_clase[indice_80], frec_acum[indice_80],
col = "#2196F3", pch = 17, cex = 1.5)
Figura 4: Ojiva de frecuencias acumuladas
# Instalar/verificar paquete e1071
if(!require(e1071)) {
install.packages("e1071", quiet = TRUE)
library(e1071)
}
# Calcular estadísticos
estadisticos <- list(
"Tamaño de muestra" = n,
"Media" = mean(Voltaje),
"Mediana" = median(Voltaje),
"Moda*" = as.numeric(names(sort(table(round(Voltaje, 1)), decreasing = TRUE)[1])),
"Desviación estándar" = sd(Voltaje),
"Varianza" = var(Voltaje),
"Coeficiente de variación" = (sd(Voltaje)/mean(Voltaje)) * 100,
"Mínimo" = min(Voltaje),
"Máximo" = max(Voltaje),
"Rango" = max(Voltaje) - min(Voltaje),
"Primer cuartil (Q1)" = as.numeric(quantile(Voltaje, 0.25)),
"Tercer cuartil (Q3)" = as.numeric(quantile(Voltaje, 0.75)),
"Rango intercuartílico (IQR)" = IQR(Voltaje),
"Asimetría (Skewness)" = skewness(Voltaje),
"Curtosis (Kurtosis)" = kurtosis(Voltaje)
)
# Función para formatear valores
formatear_valor <- function(nombre, valor) {
if(is.numeric(valor)) {
if(nombre == "Tamaño de muestra") {
return(format(round(valor, 0), big.mark = ","))
} else if(nombre == "Coeficiente de variación") {
return(paste0(round(valor, 2), "%"))
} else if(nombre %in% c("Asimetría (Skewness)", "Curtosis (Kurtosis)")) {
return(as.character(round(valor, 4)))
} else if(nombre %in% c("Varianza")) {
return(paste0(round(valor, 2), " V²"))
} else {
return(paste0(round(valor, 2), " V"))
}
} else {
return(as.character(valor))
}
}
# Crear y mostrar tabla
valores_formateados <- mapply(formatear_valor, names(estadisticos), estadisticos)
tabla_resumen <- data.frame(
"Estadístico" = names(estadisticos),
"Valor" = valores_formateados,
"Interpretación" = c(
"Número total de observaciones válidas",
"Promedio aritmético de todos los valores",
"Valor que divide la distribución en dos partes iguales",
"Valor que ocurre con mayor frecuencia",
"Medida de dispersión absoluta",
"Dispersión cuadrática de los datos",
"Medida de dispersión relativa (SD/Media × 100)",
"Valor más pequeño en la muestra",
"Valor más grande en la muestra",
"Diferencia entre máximo y mínimo",
"25% de los datos son menores que este valor",
"75% de los datos son menores que este valor",
"Diferencia entre Q3 y Q1 (dispersión del 50% central)",
"Medida de simetría de la distribución",
"Medida de apuntamiento de la distribución"
),
stringsAsFactors = FALSE)
cat("\n", rep("=", 70), "\n", sep = "")
##
## ======================================================================
cat("TABLA 2: RESUMEN DE ESTADÍSTICOS DESCRIPTIVOS\n")
## TABLA 2: RESUMEN DE ESTADÍSTICOS DESCRIPTIVOS
cat(rep("=", 70), "\n\n", sep = "")
## ======================================================================
print(tabla_resumen, row.names = FALSE, right = FALSE)
## Estadístico Valor
## Tamaño de muestra 7,704
## Media 422.53 V
## Mediana 428 V
## Moda* 480 V
## Desviación estándar 42.71 V
## Varianza 1823.89 V²
## Coeficiente de variación 10.11%
## Mínimo 0 V
## Máximo 847 V
## Rango 847 V
## Primer cuartil (Q1) 402 V
## Tercer cuartil (Q3) 450 V
## Rango intercuartílico (IQR) 48 V
## Asimetría (Skewness) -2.2183
## Curtosis (Kurtosis) 19.4388
## Interpretación
## Número total de observaciones válidas
## Promedio aritmético de todos los valores
## Valor que divide la distribución en dos partes iguales
## Valor que ocurre con mayor frecuencia
## Medida de dispersión absoluta
## Dispersión cuadrática de los datos
## Medida de dispersión relativa (SD/Media × 100)
## Valor más pequeño en la muestra
## Valor más grande en la muestra
## Diferencia entre máximo y mínimo
## 25% de los datos son menores que este valor
## 75% de los datos son menores que este valor
## Diferencia entre Q3 y Q1 (dispersión del 50% central)
## Medida de simetría de la distribución
## Medida de apuntamiento de la distribución
cat("\n* Moda aproximada (redondeada a 1 decimal)\n")
##
## * Moda aproximada (redondeada a 1 decimal)
cat("\n", rep("=", 70), "\n", sep = "")
##
## ======================================================================
cat("CONCLUSIONES Y RECOMENDACIONES\n")
## CONCLUSIONES Y RECOMENDACIONES
cat(rep("=", 70), "\n\n", sep = "")
## ======================================================================
promedio_v <- mean(Voltaje)
cv <- sd(Voltaje)/mean(Voltaje) * 100
cat("1. NIVEL DE VOLTAJE PROMEDIO:\n")
## 1. NIVEL DE VOLTAJE PROMEDIO:
cat(" • Valor promedio:", round(promedio_v, 1), "V\n")
## • Valor promedio: 422.5 V
if(promedio_v < 110) {
cat(" • Clasificación: VOLTAJE BAJO\n")
cat(" • Recomendación: Verificar reguladores y transformadores\n")
} else if(promedio_v >= 110 & promedio_v < 220) {
cat(" • Clasificación: VOLTAJE ESTÁNDAR\n")
cat(" • Situación: Adecuado para la mayoría de equipos\n")
} else if(promedio_v >= 220 & promedio_v < 380) {
cat(" • Clasificación: VOLTAJE INDUSTRIAL\n")
cat(" • Situación: Requiere equipos especializados\n")
} else {
cat(" • Clasificación: VOLTAJE MUY ALTO\n")
cat(" • Recomendación: Implementar sistemas de protección\n")
}
## • Clasificación: VOLTAJE MUY ALTO
## • Recomendación: Implementar sistemas de protección
cat("\n2. ESTABILIDAD DEL SUMINISTRO:\n")
##
## 2. ESTABILIDAD DEL SUMINISTRO:
cat(" • Coeficiente de variación:", round(cv, 1), "%\n")
## • Coeficiente de variación: 10.1 %
if(cv > 30) {
cat(" • Nivel: ALTA VARIABILIDAD\n")
cat(" • Implicación: Suministro inestable, riesgo de daño a equipos\n")
cat(" • Acción: Investigar causas de fluctuación\n")
} else if(cv > 15) {
cat(" • Nivel: VARIABILIDAD MODERADA\n")
cat(" • Implicación: Fluctuaciones dentro de parámetros aceptables\n")
} else {
cat(" • Nivel: BAJA VARIABILIDAD\n")
cat(" • Implicación: Suministro eléctrico estable y confiable\n")
}
## • Nivel: BAJA VARIABILIDAD
## • Implicación: Suministro eléctrico estable y confiable
cat("\n3. DISTRIBUCIÓN DE LOS DATOS:\n")
##
## 3. DISTRIBUCIÓN DE LOS DATOS:
cat(" • Rango operativo típico (IQR):",
round(quantile(Voltaje, 0.25), 1), "-",
round(quantile(Voltaje, 0.75), 1), "V\n")
## • Rango operativo típico (IQR): 402 - 450 V
cat(" • Este rango contiene el 50% central de las mediciones\n")
## • Este rango contiene el 50% central de las mediciones
cat("\n4. ANÁLISIS DE LA DISTRIBUCIÓN:\n")
##
## 4. ANÁLISIS DE LA DISTRIBUCIÓN:
cat(" • Concentración principal:", names(frecuencia)[indice_modal], "\n")
## • Concentración principal: [472,850]
cat(" • % de datos en intervalo modal:", round(100 * max(frecuencia_rel), 1), "%\n")
## • % de datos en intervalo modal: 9.6 %
cat(" • Nivel de concentración: ")
## • Nivel de concentración:
if(max(frecuencia_rel) > 0.5) {
cat("ALTA (más del 50% en un solo intervalo)\n")
} else if(max(frecuencia_rel) > 0.3) {
cat("MODERADA (entre 30-50% en intervalo modal)\n")
} else {
cat("BAJA (distribución más dispersa)\n")
}
## BAJA (distribución más dispersa)
cat("\n", rep("-", 70), "\n", sep = "")
##
## ----------------------------------------------------------------------
cat("INFORME GENERADO: ", format(Sys.time(), "%d de %B de %Y, %H:%M"), "\n", sep = "")
## INFORME GENERADO: 06 de diciembre de 2025, 17:38
cat("MUESTRA ANALIZADA: ", format(n, big.mark = ","), " observaciones de voltaje\n", sep = "")
## MUESTRA ANALIZADA: 7,704 observaciones de voltaje
cat(rep("-", 70), "\n", sep = "")
## ----------------------------------------------------------------------