1 Configuración y Carga de Datos

##### UNIVERSIDAD CENTRAL DEL ECUADOR #####
#### AUTOR: MARTIN SARMIENTO ####
### CARRERA: INGENIERÍA EN PETRÓLEOS #####

#### VARIABLE ESTADO OPERATIVO ####
## DATASET ##
setwd("~/R INFERENCIAL/OPERATIONAL_STATUS")
# Cargar dataset
Datos <- read.csv("Dataset_Mundial_Final.csv", sep = ";", fileEncoding = "latin1")
## Estructura de los datos
str(Datos)
'data.frame':   58978 obs. of  29 variables:
 $ ï..OBJECTID           : int  2 3 4 5 6 7 8 9 10 11 ...
 $ code                  : chr  "00001-AFG-P" "00002-AFG-P" "00003-AFG-P" "00004-AFG-P" ...
 $ plant_name            : chr  "Badghis Solar Power Plant" "Balkh solar farm" "Behsood solar farm" "Dab Pal 4 solar farm" ...
 $ country               : chr  "Afghanistan" "Afghanistan" "Afghanistan" "Afghanistan" ...
 $ operational_status    : chr  "cancelled - inferred 4 y" "cancelled - inferred 4 y" "cancelled - inferred 4 y" "shelved - inferred 2 y" ...
 $ longitude             : chr  "62,874" "67,121" "70,413" "66,239" ...
 $ latitude              : chr  "35,078" "36,714" "34,407" "33,768" ...
 $ elevation             : int  918 359 629 2288 1060 1060 1392 398 410 1012 ...
 $ area                  : chr  "6,735" "10,718" "487,729" "111,801" ...
 $ size                  : chr  "Small" "Small" "Small" "Small" ...
 $ slope                 : chr  "7,375" "0,49" "1,099" "6,162" ...
 $ slope_type            : chr  "Moderado" "Plano o casi plano" "Plano o casi plano" "Moderado" ...
 $ curvature             : chr  "-0,024" "0" "0" "0,045" ...
 $ curvature_type        : chr  "Superficies cóncavas / Valles" "Superficies planas o intermedias" "Superficies planas o intermedias" "Superficies convexas / Crestas" ...
 $ aspect                : chr  "96,77" "358,452" "36,18" "305,766" ...
 $ aspect_type           : chr  "East" "North" "Northeast" "Northwest" ...
 $ dist_to_road          : chr  "7037,104" "92,748" "112,117" "1705,255" ...
 $ ambient_temperature   : chr  "14,402" "17,875" "21,315" "8,857" ...
 $ ghi                   : chr  "5,824" "5,579" "5,805" "6,749" ...
 $ humidity              : chr  "47,743" "42,305" "36,396" "37,344" ...
 $ wind_speed            : chr  "0,039" "0,954" "0,234" "0,943" ...
 $ wind_direction        : chr  "187,481" "207,422" "255,601" "160,331" ...
 $ dt_wind               : chr  "South" "Southwest" "West" "South" ...
 $ solar_aptitude        : chr  "0,72" "0,635" "0,685" "0,659" ...
 $ solar_aptitude_rounded: int  7 6 7 7 8 8 8 6 6 4 ...
 $ solar_aptittude_class : chr  "Alta" "Alta" "Alta" "Alta" ...
 $ capacity              : chr  "32" "40" "60" "3000" ...
 $ optimal_tilt          : chr  "30" "31" "31,063" "33" ...
 $ pv_potential          : chr  "4,613" "4,408" "4,572" "5,424" ...
# Cargamos las librerias
library(dplyr)

Adjuntando el paquete: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(ggplot2)
library(gt)

2 Extraer Variable

Se realizó la estandarización y traducción de la variable operational_status mediante técnicas de mapeo en R. Esto permitió consolidar 10 categorías operativas uniformes para facilitar el tratamiento inferencial de los 58,978 datos registrados.

# Definir el orden específico 
orden_status <- c(
  "Operativo",
  "Anunciado",
  "Construcción",
  "Pre-Construcción",
  "Inactivo (Mothballed)",
  "Archivado (Shelved)",
  "Archivado (Inferred 2y)",
  "Cancelado",
  "Cancelado (Inferred 4y)",
  "Retirada"
)

# Traducción y Mapeo 
Status_Traducido <- case_when(
  grepl("cancelled - inferred 4 y", Datos$operational_status, ignore.case = TRUE) ~ "Cancelado (Inferred 4y)",
  grepl("shelved - inferred 2 y", Datos$operational_status, ignore.case = TRUE) ~ "Archivado (Inferred 2y)",
  grepl("operating", Datos$operational_status, ignore.case = TRUE) ~ "Operativo",
  grepl("announced", Datos$operational_status, ignore.case = TRUE) ~ "Anunciado",
  grepl("pre-construction", Datos$operational_status, ignore.case = TRUE) ~ "Pre-Construcción", 
  grepl("construction", Datos$operational_status, ignore.case = TRUE) ~ "Construcción",
  grepl("mothballed", Datos$operational_status, ignore.case = TRUE) ~ "Inactivo (Mothballed)",
  grepl("shelved", Datos$operational_status, ignore.case = TRUE) ~ "Archivado (Shelved)",
  grepl("cancelled", Datos$operational_status, ignore.case = TRUE) ~ "Cancelado",
  grepl("retired", Datos$operational_status, ignore.case = TRUE) ~ "Retirada"
)

# Actualizamos dataset
Datos$operational_status <- Status_Traducido

# Crear el Factor
Status <- factor(
  Status_Traducido,
  levels = orden_status,
  ordered = TRUE
)

# Tabla de distribución de frecuencias
TDF_status <- table(Status)

3 Tabla de Distribución de Frecuencias

Se calculó la distribución de frecuencias absolutas (\(n_i\)) y relativas (\(h_i\)). Los resultados determinan que el estado Operativo predomina con el 80.60%, seguido por la fase de Pre-Construcción con un 10.59%.

# Tabla de frecuencias absolutas
Tabla <- as.data.frame(TDF_status)

# Renombrar columna de frecuencia
colnames(Tabla) <- c("Status", "ni")

# Asegurar tipo character
Tabla$Status <- as.character(Tabla$Status)

# Crear porcentaje
Tabla$`hi (%)` <- (Tabla$ni / sum(Tabla$ni)) * 100

# Fila total
fila_total_status <- tibble(
  Status = "TOTAL",
  ni = sum(Tabla$ni),
  `hi (%)` = sum(Tabla$`hi (%)`)
)

# Unir fila total
tabla_Final <- bind_rows(Tabla, fila_total_status)

# TABLA GT
tabla_status_gt <- tabla_Final %>%
  gt() %>%
  tab_header(
    title = md("**Tabla N°1 de Distribución de Frecuencias del Estado Operativo de las Plantas Solares**")
  ) %>%
  tab_source_note(
    source_note = "Autor: Martin Sarmiento"
  ) %>%
  cols_label(
    Status = "Estado Operativo",
    ni = "Frecuencia (ni)",
    `hi (%)` = "Porcentaje (hi%)"
  ) %>%
  fmt_number(
    columns = `hi (%)`,
    decimals = 2
  ) %>%
  tab_options(
    heading.title.font.size = px(16),
    column_labels.background.color = "#F0F0F0"
  )

# Mostrar tabla
tabla_status_gt
Tabla N°1 de Distribución de Frecuencias del Estado Operativo de las Plantas Solares
Estado Operativo Frecuencia (ni) Porcentaje (hi%)
Operativo 47538 80.60
Anunciado 1382 2.34
Construcción 2005 3.40
Pre-Construcción 6246 10.59
Inactivo (Mothballed) 9 0.02
Archivado (Shelved) 246 0.42
Archivado (Inferred 2y) 530 0.90
Cancelado 564 0.96
Cancelado (Inferred 4y) 426 0.72
Retirada 32 0.05
TOTAL 58978 100.00
Autor: Martin Sarmiento

4 Análisis Gráfico

4.1 Diagramas de Barras de Cantidad

Mediante un diagrama de barras de cantidad, se identificó visualmente la alta heterogeneidad de la variable. Esta observación justificó la división del análisis en dos agrupaciones (Fase Activa e Inactiva) para aplicar modelos de probabilidad específicos según el comportamiento de cada segmento.

# Reordenar los niveles del factor para que las barras aparezcan en la secuencia correcta
Tabla$Status <- factor(Tabla$Status, levels = orden_status)

# Extraemos los valores para graficar
alturas_ni <- Tabla$ni
nombres_eje <- Tabla$Status

# Calculamos un límite 
limite_y_ni <- max(alturas_ni, na.rm = TRUE) * 1.2

par(mar = c(13, 6, 4, 2))
barplot(height = alturas_ni,
        names.arg = nombres_eje,
        main = "Gráfica N°1: Distribución de Cantidad de las Plantas Solares por Estado Operativo",
        ylab = "",
        col = "#D8BFD8",
        las = 2,
        cex.names = 0.6,
        cex.main = 0.9,
        ylim = c(0, 58978))
mtext("Cantidad", side = 2, line = 4.5, cex = 1, font = 1)
mtext("Estado Operativo", side = 1, line = 10)

5 Agrupación 1 (Fase Activa)

Se realiza un mapeo asignando valores a los estados de desarrollo. Este proceso permite cuantificar la variable cualitativa para ajustar el modelo geométrico a la frecuencia observada.

# Definimos niveles
niveles_Geom <- c("Pre-Construcción", "Anunciado", "Construcción")

# Extracción
Datos_G1_Geom <- subset(Datos, operational_status %in% niveles_Geom)
Datos_G1_Geom$operational_status <- factor(Datos_G1_Geom$operational_status, 
                                           levels = niveles_Geom, ordered = TRUE)

# Crear Tabla de Frecuencias y Mapeo
TDF_G1_Geom <- as.data.frame(table(Datos_G1_Geom$operational_status))
colnames(TDF_G1_Geom) <- c("Status", "ni")

# Mapeo
TDF_G1_Geom$X <- 0:(nrow(TDF_G1_Geom) - 1)

TDF_G1_Geom$hi <- TDF_G1_Geom$ni / sum(TDF_G1_Geom$ni)

# Visualización del Mapeo
TDF_G1_Geom %>% 
  select(Status, X, ni, hi) %>%
  gt() %>% 
  tab_header(
    title = md("**Tabla N°2 de Distribución de Frecuencias del Estado Operativo de las Plantas Solares - Mapeado**")) %>%
  tab_source_note(source_note = "Autor: Martin Sarmiento") %>%
  cols_label(
    Status = "Estado Operativo",
    X = "Valor Asignado",
    ni = "Frecuencia (ni)",
    hi = "Porcentaje (hi%)"
  ) %>%
  fmt_number(columns = hi, decimals = 4) %>%
  tab_options(
    heading.title.font.size = px(16),
    heading.subtitle.font.size = px(14),
    column_labels.background.color = "#F0F0F0"
  )
Tabla N°2 de Distribución de Frecuencias del Estado Operativo de las Plantas Solares - Mapeado
Estado Operativo Valor Asignado Frecuencia (ni) Porcentaje (hi%)
Pre-Construcción 0 6246 0.6484
Anunciado 1 1382 0.1435
Construcción 2 2005 0.2081
Autor: Martin Sarmiento

5.1 Conjentura del Modelo (Geométrico)

Se seleccionaron los estados de Pre-Construcción, Anunciado y Construcción para analizar el comportamiento del desarrollo inicial de los proyectos. Se aplica un Modelo Geométrico bajo la premisa de que la probabilidad de encontrar un proyecto disminuye conforme avanza hacia etapas más avanzadas y complejas, concentrando la mayor frecuencia en la fase inicial de Pre-Construcción.

# Usamos la columna X que acabamos de Mapear
n_total_Geom <- sum(TDF_G1_Geom$ni)

# Parámetros Geométricos 
media_obs_B <- sum(TDF_G1_Geom$X * TDF_G1_Geom$ni) / n_total_Geom
prob_geom_B <- 1 / (media_obs_B + 1)

# Probabilidades Teóricas
P_Geom_B <- dgeom(TDF_G1_Geom$X, prob = prob_geom_B)
P_Geom_B <- P_Geom_B / sum(P_Geom_B) 

# Gráfico
par(mar = c(8, 4, 4, 2))
barplot(rbind(TDF_G1_Geom$hi, P_Geom_B), 
        beside = TRUE,
        main = "Gráfica N°2: Comparado de lo Observado frente a lo Esperado del Estado Operativo de las Plantas Solares",
        ylab = "Porcentaje (%)",
        names.arg = TDF_G1_Geom$Status, 
        col = c("#D8BFD8", "purple"),
        legend.text = c("Observado", "Esperado"), 
        args.legend = list(x = "topright"),
        las = 2, 
        cex.names = 0.8,
        cex.main = 0.7,
        ylim = c(0, 1))
mtext("Estado Operativo", side = 1, line = 6)

5.2 Test de Pearson

# Definir Frecuencia Observada y Esperada
Fo_B <- TDF_G1_Geom$hi
Fe_B <- P_Geom_B

# Gráfico de Correlación
plot(Fo_B, Fe_B, 
     main = "Gráfica N°3: Correlación del Modelo Observado y Esperado del Estado Operativo de las Plantas Solares",
     cex.main = 0.7,
     xlab = "Frecuencia Observada", 
     ylab = "Frecuencia Esperada", 
     pch = 19, col = "#68228B")
abline(lm(Fe_B ~ Fo_B), col = "red", lwd = 2)

# Cálculo del coeficiente
Correlacion_B <- cor(Fo_B, Fe_B) * 100
Correlacion_B
[1] 93.02826

5.3 Test de Chi-cuadrado

# Cálculo de Chi-cuadrado
x2_B <- sum(((Fo_B - Fe_B)^2) / Fe_B)

# Grados de libertad (k - 1)
gl_B <- length(Fo_B) - 1

# Valor crítico
vc_B <- qchisq(0.95, gl_B)

# Mostrar resultados
x2_B
[1] 0.2111809
vc_B
[1] 5.991465
# Validación lógica
x2_B < vc_B
[1] TRUE

5.4 Tabla Resumen del Test

# Crear data frame resumen
tabla_resumen_B <- data.frame(
  Variable = "Estado Operativo",
  Pearson = round(Correlacion_B, 2),
  Chi2 = round(x2_B, 4),
  Umbral = round(vc_B, 2),
  Resultado = x2_B < vc_B
)

# Visualizar con GT
tabla_resumen_B %>% 
  gt() %>% 
  cols_label(
    Variable = ("Variable"),       
    Pearson  = "Test Pearson (%)",
    Chi2     = ("Chi Cuadrado"), 
    Umbral   = "Umbral de Aceptación",
    Resultado = "Resultado"
  ) %>%
  tab_header(
    title = md("**Tabla N°3 Resumen del Test de Bondad al Modelo de Probabilidad**")) %>%
  tab_source_note(
    source_note = "Autor: Martin Sarmiento") %>%
  cols_align(
    align = "center", 
    everything()) %>%
tab_options(
    heading.title.font.size = px(16),
    column_labels.background.color = "#F0F0F0")
Tabla N°3 Resumen del Test de Bondad al Modelo de Probabilidad
Variable Test Pearson (%) Chi Cuadrado Umbral de Aceptación Resultado
Estado Operativo 93.03 0.2112 5.99 TRUE
Autor: Martin Sarmiento

5.5 Cálculo de Probabilidades

¿Cuál es la probabilidad de seleccionar una planta solar que apenas se encuentre en fase de Pre-Construcción?

prob_pre <- dgeom(0, prob = prob_geom_B)

paste0("La probabilidad estimada para la fase de Pre-Construcción es de: ", 
       round(prob_pre * 100, 2), "%")
[1] "La probabilidad estimada para la fase de Pre-Construcción es de: 64.11%"

6 Agrupación 2 (Fase Inactiva)

Se asignan valores numéricos a las categorías de inactividad. Esta codificación es el requisito técnico para parametrizar el modelo binomial y evaluar su ajuste estadístico.

# Definimos niveles
niveles_G2 <- c("Inactivo (Mothballed)", "Archivado (Shelved)", "Archivado (Inferred 2y)", "Cancelado", "Cancelado (Inferred 4y)", "Retirada")

# Extracción
Datos_G2 <- subset(Datos, operational_status %in% niveles_G2)
Datos_G2$operational_status <- factor(Datos_G2$operational_status, levels = niveles_G2)

# Crear Tabla de Frecuencias y Mapeo
TDF_G2 <- as.data.frame(table(Datos_G2$operational_status))
colnames(TDF_G2) <- c("Status", "ni")

# Mapeo
TDF_G2$X <- 0:(nrow(TDF_G2) - 1)

TDF_G2$hi <- TDF_G2$ni / sum(TDF_G2$ni)

# Visualización del Mapeo
TDF_G2 %>% 
  select(Status, X, ni, hi) %>%
  gt() %>% 
  tab_header(
    title = md("**Tabla N°4 de Distribución de Frecuencias del Estado Operativo de las Plantas Solares - Mapeado**")) %>%
  tab_source_note(source_note = "Autor: Martin Sarmiento") %>%
  cols_label(
    Status = "Estado Operativo",
    X = "Valor Asignado",
    ni = "Frecuencia (ni)",
    hi = "Porcentaje (hi%)"
  ) %>%
  fmt_number(columns = hi, decimals = 4) %>%
  tab_options(
    heading.title.font.size = px(16),
    heading.subtitle.font.size = px(14),
    column_labels.background.color = "#F0F0F0"
  )
Tabla N°4 de Distribución de Frecuencias del Estado Operativo de las Plantas Solares - Mapeado
Estado Operativo Valor Asignado Frecuencia (ni) Porcentaje (hi%)
Inactivo (Mothballed) 0 9 0.0050
Archivado (Shelved) 1 246 0.1361
Archivado (Inferred 2y) 2 530 0.2933
Cancelado 3 564 0.3121
Cancelado (Inferred 4y) 4 426 0.2357
Retirada 5 32 0.0177
Autor: Martin Sarmiento

6.1 Conjentura del Modelo (Binomial)

Esta agrupación comprende los estados de pausa, cancelación y retiro (Inactivo, Archivado, Cancelado y Retirada). Se propone un Modelo Binomial para representar este segmento, ya que permite evaluar la probabilidad de ocurrencia de estos eventos dentro de un sistema cerrado de categorías de falla, buscando identificar una tendencia central en los proyectos que no lograron su ejecución operativa.

# Usamos la columna X que acabamos de mapear
n_total_G2 <- sum(TDF_G2$ni)

# Parámetros Binomiales
size_binom2 <- nrow(TDF_G2) - 1
media_G2 <- sum(TDF_G2$X * TDF_G2$ni) / n_total_G2
prob_p2 <- media_G2 / size_binom2

# Probabilidades Teóricas
P_Binom_G2 <- dbinom(TDF_G2$X, size = size_binom2, prob = prob_p2)

# Gráfico
par(mar = c(10, 4, 4, 2))
barplot(rbind(TDF_G2$hi, P_Binom_G2), 
        beside = TRUE,
        main = "Gráfica N°4: Comparado de lo Observado frente a lo Esperado del Estado Operativo de las Plantas Solares",
        ylab = "Porcentaje (%)",
        names.arg = TDF_G2$Status, 
        col = c("#D8BFD8", "purple"),
        legend.text = c("Observado", "Esperado"), 
        args.legend = list(x = "topright"),
        las = 2, 
        cex.names = 0.8,
        cex.main = 0.7,
        ylim = c(0, 1))
mtext("Estado Operativo", side = 1, line = 8)

6.2 Test de Pearson

# Definir Frecuencia Observada y Esperada
Fo_G2 <- TDF_G2$hi
Fe_G2 <- P_Binom_G2

# Gráfico de Correlación
plot(Fo_G2, Fe_G2, 
     main = "Gráfica N°5: Correlación del Modelo Observado y Esperado del Estado Operativo de las Plantas Solares",
     cex.main = 0.7,
     xlab = "Frecuencia Observada", 
     ylab = "Frecuencia Esperada", 
     pch = 19, col = "#68228B")
abline(lm(Fe_G2 ~ Fo_G2), col = "red", lwd = 2)

# Cálculo del coeficiente
Correlacion_G2 <- cor(Fo_G2, Fe_G2) * 100
Correlacion_G2
[1] 98.19349

6.3 Test de Chi-cuadrado

# Cálculo de Chi-cuadrado
x2_G2 <- sum(((Fo_G2 - Fe_G2)^2) / Fe_G2)

# Grados de libertad (k - 1)
gl_G2 <- length(Fo_G2) - 1

# Valor crítico
vc_G2 <- qchisq(0.95, gl_G2)

# Mostrar resultados
x2_G2
[1] 0.04103974
vc_G2
[1] 11.0705
# Validación lógica
x2_G2 < vc_G2
[1] TRUE

6.4 Tabla Resumen del Test

# Crear data frame resumen
tabla_resumen_G2 <- data.frame(
  Variable = "Fases Inactivas",
  Pearson = round(Correlacion_G2, 2),
  Chi2 = round(x2_G2, 4),
  Umbral = round(vc_G2, 2),
  Resultado = x2_G2 < vc_G2
)

# Visualizar con GT
tabla_resumen_G2 %>% 
  gt() %>% 
  cols_label(
    Variable = ("Variable"),       
    Pearson  = "Test Pearson (%)",
    Chi2     = ("Chi Cuadrado"), 
    Umbral   = "Umbral de Aceptación",
    Resultado = "Resultado"
  ) %>%
  tab_header(
    title = md("**Tabla N°5 Resumen del Test de Bondad al Modelo de Probabilidad**")) %>%
  tab_source_note(
    source_note = "Autor: Martin Sarmiento") %>%
  cols_align(
    align = "center", 
    everything()) %>%
tab_options(
    heading.title.font.size = px(16),
    column_labels.background.color = "#F0F0F0")
Tabla N°5 Resumen del Test de Bondad al Modelo de Probabilidad
Variable Test Pearson (%) Chi Cuadrado Umbral de Aceptación Resultado
Fases Inactivas 98.19 0.041 11.07 TRUE
Autor: Martin Sarmiento

6.5 Cálculo de Probabilidades

¿Cuál es la probabilidad estimada de que un nuevo proyecto se encuentre catalogado específicamente como Archivado (Shelved)?

prob_shelved <- dbinom(1, size = size_binom2, prob = prob_p2)

paste0("La probabilidad estimada de que un proyecto esté Archivado (Shelved) es de: ", 
       round(prob_shelved * 100, 2), "%")
[1] "La probabilidad estimada de que un proyecto esté Archivado (Shelved) es de: 12.24%"

7 Conclusiones

El análisis probabilístico permitió modelar el estado operativo de las plantas solares a nivel mundial mediante un modelo geométrico para la fase activa y un modelo binomial para la fase inactiva. Los resultados muestran que la mayoría de los proyectos en desarrollo se concentran en la etapa de pre-construcción, mientras que en las fases de inactividad predominan los proyectos archivados y cancelados.

Las pruebas de bondad de ajuste, con coeficientes de Pearson del 93.03% y 98.19% respectivamente, confirman que ambos modelos representan adecuadamente los datos observados. Esto evidencia una descripción estadística coherente del ciclo de desarrollo y de las causas de paralización en la infraestructura de energía solar a gran escala.