1 Configuración y Carga de Datos

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


#### VARIABLE AREA ####
## DATASET ##
setwd("~/R/AREA")
# Cargar dataset
Datos <- read.csv("DataSet_prov.csv", sep = ";", dec = ",", fileEncoding = "latin1")
# Estructura de los datos
str(Datos)
## 'data.frame':    5075 obs. of  30 variables:
##  $ FID_                  : int  0 2 3 4 5 6 10 11 12 13 ...
##  $ OBJECTID              : int  127 129 130 131 132 133 137 138 139 140 ...
##  $ code                  : chr  "00127-ARG-P" "00129-ARG-G" "00130-ARG-P" "00131-ARG-P" ...
##  $ plant_name            : chr  "Aconcagua solar farm" "Altiplano 200 Solar Power Plant" "Altiplano 200 Solar Power Plant" "Anchoris solar farm" ...
##  $ country               : chr  "Argentina" "Argentina" "Argentina" "Argentina" ...
##  $ operational_status    : chr  "announced" "operating" "operating" "construction" ...
##  $ longitude             : num  -68.9 -66.9 -66.9 -68.9 -70.3 ...
##  $ latitude              : num  -33 -24.1 -24.1 -33.3 -37.4 ...
##  $ elevation             : int  929 4000 4000 937 865 858 570 1612 665 3989 ...
##  $ area                  : num  250 4397290 5774 645 241 ...
##  $ size                  : chr  "Pequeña" "Grande" "Pequeña" "Pequeña" ...
##  $ slope                 : num  0.574 1.603 6.243 0.903 1.791 ...
##  $ slope_type            : chr  "Plano o casi plano" "Plano o casi plano" "Moderado" "Plano o casi plano" ...
##  $ curvature             : num  0.000795 -0.002781 -0.043699 0.002781 -0.002384 ...
##  $ curvature_type        : chr  "Superficies planas o intermedias" "Superficies planas o intermedias" "Superficies cóncavas / Valles" "Superficies planas o intermedias" ...
##  $ aspect                : num  55.1 188.7 270.9 108.4 239.3 ...
##  $ aspect_type           : chr  "Northeast" "South" "West" "East" ...
##  $ dist_to_road          : num  127 56015 52697 336 34 ...
##  $ ambient_temperature   : num  12.6 6.8 6.8 13.1 11.4 ...
##  $ ghi                   : num  6.11 8.01 7.88 6.12 6.22 ...
##  $ humidity              : num  53.7 53.7 53.7 53.7 53.7 ...
##  $ wind_speed            : num  3.78 7.02 8.33 3.87 6.56 ...
##  $ wind_direction        : num  55.1 55.1 55.1 55.1 55.1 ...
##  $ dt_wind               : chr  "Northeast" "Northeast" "Northeast" "Northeast" ...
##  $ solar_aptitude        : num  0.746 0.8 0.727 0.595 0.657 ...
##  $ solar_aptitude_rounded: int  7 8 7 6 7 7 7 8 7 8 ...
##  $ solar_aptittude_class : chr  "Alta" "Alta" "Alta" "Media" ...
##  $ capacity              : num  25 101 107 180 20 ...
##  $ optimal_tilt          : int  31 26 26 31 33 30 31 29 31 27 ...
##  $ pv_potential          : num  4.98 6.39 6.39 4.97 5 ...
# 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(gt)
library(e1071)

2 Cálculo de Intervalos y Frecuencias

# Extraer variable
Variable <- na.omit(Datos$area)
N <- length(Variable)

# CÁLCULO LÍMITES DECIMALES
min_dec <- min(Variable)
max_dec <- max(Variable)
k_dec <- floor(1 + 3.322 * log10(N))
rango_dec <- max(Variable) - min(Variable)
amplitud_dec <- rango_dec / k_dec

# Cortes exactos
cortes_dec <- seq(min(Variable), max(Variable), length.out = k_dec + 1)
cortes_dec[length(cortes_dec)] <- max(Variable) + 0.0001

# Frecuencias
inter_dec <- cut(Variable, breaks = cortes_dec, include.lowest = TRUE, right = FALSE)
ni_dec <- as.vector(table(inter_dec))

# CÁLCULOS MATEMÁTICOS
hi_dec <- (ni_dec / N) * 100
Ni_asc_dec <- cumsum(ni_dec)
Hi_asc_dec <- cumsum(hi_dec)
Ni_desc_dec <- rev(cumsum(rev(ni_dec)))
Hi_desc_dec <- rev(cumsum(rev(hi_dec)))

# Dataframe Decimal
TDF_Decimal <- data.frame(
  Li = cortes_dec[1:k_dec],
  Ls = cortes_dec[2:(k_dec+1)],
  MC = (cortes_dec[1:k_dec] + cortes_dec[2:(k_dec+1)]) / 2,
  ni = ni_dec,
  hi = hi_dec,
  Ni_asc = Ni_asc_dec,
  Ni_desc = Ni_desc_dec,
  Hi_asc = Hi_asc_dec,
  Hi_desc = Hi_desc_dec)


# CÁLCULO LÍMITES ENTEROS
BASE <- 10
min_int <- floor(min(Variable) / BASE) * BASE
max_int <- ceiling(max(Variable) / BASE) * BASE
k_int_sug <- floor(1 + 3.322 * log10(N))
Rango_int <- max_int - min_int
Amplitud_raw <- Rango_int / k_int_sug

Amplitud_int <- ceiling(Amplitud_raw / 10) * 10
if(Amplitud_int == 0) Amplitud_int <- 10

cortes_int <- seq(from = min_int, by = Amplitud_int, length.out = k_int_sug + 2)
cortes_int <- cortes_int[cortes_int <= (max_int + Amplitud_int)]

while(max(cortes_int) < max(Variable)) {
  cortes_int <- c(cortes_int, max(cortes_int) + Amplitud_int)
}

K_real <- length(cortes_int) - 1
lim_inf_int <- cortes_int[1:K_real]
lim_sup_int <- cortes_int[2:(K_real+1)]

# Frecuencias
inter_int <- cut(Variable, breaks = cortes_int, include.lowest = TRUE, right = FALSE)
ni_int <- as.vector(table(inter_int))

# CÁLCULOS MATEMÁTICOS
hi_int <- (ni_int / N) * 100
Ni_asc_int <- cumsum(ni_int)
Hi_asc_int <- cumsum(hi_int)
Ni_desc_int <- rev(cumsum(rev(ni_int)))
Hi_desc_int <- rev(cumsum(rev(hi_int)))

# Dataframe Entero
TDF_Enteros <- data.frame(
  Li = lim_inf_int,
  Ls = lim_sup_int,
  MC = (lim_inf_int + lim_sup_int) / 2,
  ni = ni_int,
  hi = hi_int,
  Ni_asc = Ni_asc_int,
  Ni_desc = Ni_desc_int,
  Hi_asc = Hi_asc_int,
  Hi_desc = Hi_desc_int)

3 Tabla de Distribución de Frecuencias

3.1 Tabla con Límites Decimales

# Crear Dataframe 
TDF_Dec_Final <- data.frame(
  Li      = as.character(round(TDF_Decimal$Li, 2)),
  Ls      = as.character(round(TDF_Decimal$Ls, 2)),
  MC      = as.character(round(TDF_Decimal$MC, 2)),
  ni      = as.character(TDF_Decimal$ni),
  hi      = as.character(round(TDF_Decimal$hi, 2)),
  Ni_asc  = as.character(TDF_Decimal$Ni_asc),
  Ni_desc = as.character(TDF_Decimal$Ni_desc),
  Hi_asc  = as.character(round(TDF_Decimal$Hi_asc, 2)),
  Hi_desc = as.character(round(TDF_Decimal$Hi_desc, 2))
)

# Calcular Totales
totales_dec <- c("TOTAL", "-", "-", sum(TDF_Decimal$ni), round(sum(TDF_Decimal$hi), 2), "-", "-", "-", "-")
TDF_Dec_Final <- rbind(TDF_Dec_Final, totales_dec)

# Generar GT
TDF_Dec_Final %>%
 gt() %>%
 tab_header(title = md("**Tabla N°1 de Distribución de Frecuencias del Área (m²) de las Plantas Solares**")) %>%
 cols_label(
  Li = "Lim. Inf", 
  Ls = "Lim. Sup", 
  MC = "Marca Clase",
  ni = "Frec. Abs (ni)", 
  hi = "Frec. Rel (%)",
  Ni_asc = "Ni (Asc)", 
  Ni_desc = "Ni (Desc)",
  Hi_asc = "Hi Asc (%)", 
  Hi_desc = "Hi Desc (%)"
 ) %>%
 cols_align(align = "center", columns = everything()) %>%
 tab_options(heading.title.font.size = px(14), column_labels.background.color = "#F0F0F0")
Tabla N°1 de Distribución de Frecuencias del Área (m²) de las Plantas Solares
Lim. Inf Lim. Sup Marca Clase Frec. Abs (ni) Frec. Rel (%) Ni (Asc) Ni (Desc) Hi Asc (%) Hi Desc (%)
1 1311616.31 655808.65 4960 97.73 4960 5075 97.73 100
1311616.31 2623231.62 1967423.96 68 1.34 5028 115 99.07 2.27
2623231.62 3934846.92 3279039.27 25 0.49 5053 47 99.57 0.93
3934846.92 5246462.23 4590654.58 11 0.22 5064 22 99.78 0.43
5246462.23 6558077.54 5902269.88 6 0.12 5070 11 99.9 0.22
6558077.54 7869692.85 7213885.19 1 0.02 5071 5 99.92 0.1
7869692.85 9181308.15 8525500.5 0 0 5071 4 99.92 0.08
9181308.15 10492923.46 9837115.81 0 0 5071 4 99.92 0.08
10492923.46 11804538.77 11148731.12 3 0.06 5074 4 99.98 0.08
11804538.77 13116154.08 12460346.42 0 0 5074 1 99.98 0.02
13116154.08 14427769.38 13771961.73 0 0 5074 1 99.98 0.02
14427769.38 15739384.69 15083577.04 0 0 5074 1 99.98 0.02
15739384.69 17051000 16395192.35 1 0.02 5075 1 100 0.02
TOTAL - - 5075 100 - - - -

3.2 Tabla con Límites Enteros

# Crear Dataframe 
TDF_Int_Final <- data.frame(
  Li      = as.character(TDF_Enteros$Li),
  Ls      = as.character(TDF_Enteros$Ls),
  MC      = as.character(TDF_Enteros$MC),
  ni      = as.character(TDF_Enteros$ni),
  hi      = as.character(round(TDF_Enteros$hi, 2)),
  Ni_asc  = as.character(TDF_Enteros$Ni_asc),
  Ni_desc = as.character(TDF_Enteros$Ni_desc),
  Hi_asc  = as.character(round(TDF_Enteros$Hi_asc, 2)),
  Hi_desc = as.character(round(TDF_Enteros$Hi_desc, 2))
)

# Calcular Totales
totales_int <- c("TOTAL", "-", "-", sum(TDF_Enteros$ni), round(sum(TDF_Enteros$hi), 2), "-", "-", "-", "-")
TDF_Int_Final <- rbind(TDF_Int_Final, totales_int)

# Generar GT
TDF_Int_Final %>%
 gt() %>%
 tab_header(title = md("**Tabla N°2 de Distribución de Frecuencias del Área (m²) de las Plantas Solares**")) %>%
 cols_label(
  Li = "Lim. Inf", 
  Ls = "Lim. Sup", 
  MC = "Marca Clase",
  ni = "Frec. Abs (ni)", 
  hi = "Frec. Rel (%)",
  Ni_asc = "Ni (Asc)", 
  Ni_desc = "Ni (Desc)",
  Hi_asc = "Hi Asc (%)",
  Hi_desc = "Hi Desc (%)"
 ) %>%
 cols_align(align = "center", columns = everything()) %>%
 tab_options(heading.title.font.size = px(14), column_labels.background.color = "#F0F0F0")
Tabla N°2 de Distribución de Frecuencias del Área (m²) de las Plantas Solares
Lim. Inf Lim. Sup Marca Clase Frec. Abs (ni) Frec. Rel (%) Ni (Asc) Ni (Desc) Hi Asc (%) Hi Desc (%)
0 1311620 655810 4960 97.73 4960 5075 97.73 100
1311620 2623240 1967430 68 1.34 5028 115 99.07 2.27
2623240 3934860 3279050 25 0.49 5053 47 99.57 0.93
3934860 5246480 4590670 11 0.22 5064 22 99.78 0.43
5246480 6558100 5902290 6 0.12 5070 11 99.9 0.22
6558100 7869720 7213910 1 0.02 5071 5 99.92 0.1
7869720 9181340 8525530 0 0 5071 4 99.92 0.08
9181340 10492960 9837150 0 0 5071 4 99.92 0.08
10492960 11804580 11148770 3 0.06 5074 4 99.98 0.08
11804580 13116200 12460390 0 0 5074 1 99.98 0.02
13116200 14427820 13772010 0 0 5074 1 99.98 0.02
14427820 15739440 15083630 0 0 5074 1 99.98 0.02
15739440 17051060 16395250 1 0.02 5075 1 100 0.02
TOTAL - - 5075 100 - - - -

4 Análisis Gráfico

4.1 Histogramas de Cantidad

par(mar = c(8, 5, 5, 2)) 
barplot(TDF_Enteros$ni, 
        names.arg = TDF_Enteros$MC,
        main = "",
        xlab = "", 
        ylab = "Cantidad",
        col = "#E3E0AC",
        space = 0, 
        las = 2, 
        cex.names = 0.7)
mtext("Área (m²)", side = 1, line = 6)

mtext("Gráfica N°1: Distribución de Cantidad de Plantas Solares por el Área", 
      side = 3, 
      line = 2, 
      adj = 0.5, 
      cex = 0.9, 
      font = 2)

par(mar = c(8, 5, 4, 2))
barplot(TDF_Enteros$ni, 
        main="",
        xlab = "",
        ylab = "Cantidad",
        names.arg = TDF_Enteros$MC,
        col = "#E3E0AC",
        space = 0,
        cex.names = 0.7,
        las = 2,
        ylim = c(0, sum(TDF_Enteros$ni))) 
mtext("Área (m²)", side = 1, line = 6)

mtext("Gráfica N°2: Distribución de Cantidad de Plantas Solares por el Área", 
      side = 3, 
      line = 2, 
      adj = 0.5, 
      cex = 0.9, 
      font = 2)

4.2 Histogramas Porcentuales

par(mar = c(8, 5, 5, 2))
bp3 <- barplot(TDF_Enteros$hi, 
        main = "",
        xlab = "",
        ylab = "Porcentaje (%)",
        col = "#E3E0AC",
        space = 0,
        names.arg = TDF_Enteros$MC,
        cex.names = 0.7,
        las = 2,
        ylim = c(0, max(TDF_Enteros$hi) * 1.2))
mtext("Área (m²)", side = 1, line = 6)

mtext("Gráfica N°3: Distribución Porcentual de las Plantas Solares por el Área", 
      side = 3, 
      line = 2, 
      adj = 0.5, 
      cex = 0.9, 
      font = 2)

text(x = bp3, 
     y = TDF_Enteros$hi, 
     labels = paste0(round(TDF_Enteros$hi, 1), "%"), 
     pos = 3, cex = 0.6, col = "black")

par(mar = c(8, 5, 5, 2))
bp4 <- barplot(TDF_Enteros$hi, 
        main = "",
        xlab = "",
        ylab = "Porcentaje (%)",
        col = "#E3E0AC",
        space = 0,
        names.arg = TDF_Enteros$MC,
        las = 2,
        cex.names = 0.7,
        ylim = c(0, 110)) 
mtext("Área (m²)", side = 1, line = 6)

mtext("Gráfica N°4: Distribución Porcentual de las Plantas Solares por el Área", 
      side = 3, 
      line = 2, 
      adj = 0.5, 
      cex = 0.9, 
      font = 2)

text(x = bp4, 
     y = TDF_Enteros$hi, 
     labels = paste0(round(TDF_Enteros$hi, 1), "%"), 
     pos = 3, cex = 0.6, col = "black")

4.3 Diagrama de Cajas (Boxplot)

par(mar = c(5, 5, 4, 2))
boxplot(Variable, 
        horizontal = TRUE,
        col = "#E3E0AC",
        xlab = "Área (m²)",
        cex.main = 0.9,
         main = "Gráfica N°5: Distribución del Área en las Plantas Solares")

4.4 Ojivas

par(mar = c(5, 5, 7, 10), xpd = TRUE)

# Coordenadas
x_asc <- TDF_Enteros$Ls
x_desc <- TDF_Enteros$Li
y_asc <- TDF_Enteros$Ni_asc
y_desc <- TDF_Enteros$Ni_desc

# 1. Dibujar la Ascendente 
plot(x_asc, y_asc,
     type = "b", 
     main = "",
     xlab = "Área (m²)",
     ylab = "Frecuencia acumulada",
     col = "black",
     pch = 19, 
     xlim = c(min(x_desc), max(x_asc)), 
     ylim = c(0, sum(TDF_Enteros$ni)),
     bty = "l"
)

# 2. Agregar la Descendente 
lines(x_desc, y_desc, col = "#BDB76B", type = "b", pch = 19)

grid()
mtext("Gráfica N°6: Ojivas Ascendentes y Descendentes de la\nDistribución del Área en las Plantas Solares", 
      side = 3, 
      line = 3, 
      adj = 0.5, 
      cex = 0.9, 
      font = 2)

legend("right", 
       legend = c("Ascendente", "Descendente"), 
       col = c("black", "#BDB76B"), 
       lty = 1, 
       pch = 1, 
       cex = 0.6, 
       inset = c(0.05, 0.05),
       bty = "n")

5 Indicadores Estadísticos

## INDICADORES DE TENDENCIA CENTRAL
# Media aritmética
media <- round(mean(Variable), 2)

# Mediana
mediana <- round(median(Variable), 2)

# Moda
max_frecuencia <- max(TDF_Enteros$ni)
moda_vals <- TDF_Enteros$MC[TDF_Enteros$ni == max_frecuencia]
moda_txt <- paste(round(moda_vals, 2), collapse = ", ")

## INDICADORES DE DISPERSIÓN
# Varianza
varianza <- var(Variable)

# Desviación Estándar
sd_val <- sd(Variable)

# Coeficiente de Variación
cv <- round((sd_val / abs(media)) * 100, 2)

## INDICADORES DE FORMA
# Coeficiente de Asimetría
asimetria <- skewness(Variable, type = 2)

# Curtosis
curtosis <- kurtosis(Variable)

# Outliers
Q1 <- quantile(Variable, 0.25)
Q3 <- quantile(Variable, 0.75)
IQR_val <- Q3 - Q1
lim_inf <- Q1 - 1.5 * IQR_val
lim_sup <- Q3 + 1.5 * IQR_val

outliers_data <- Variable[Variable < lim_inf | Variable > lim_sup]
num_outliers <- length(outliers_data)

if(num_outliers > 0){
  rango_outliers <- paste0(num_outliers, " [", round(min(outliers_data), 2), "; ", round(max(outliers_data), 2), "]")
} else {
  rango_outliers <- "0 [Sin Outliers]"
}


tabla_indicadores <- data.frame(
 "Variable" = c("Área (m²)"),
 "Rango_MinMax" = paste0("[", round(min(Variable), 2), "; ", round(max(Variable), 2), "]"),
 "X" = c(media),
 "Me" = c(mediana),
 "Mo" = c(moda_txt),
 "V" = c(varianza),
 "Sd" = c(sd_val),
 "Cv" = c(cv),
 "As" = c(asimetria),
 "K" = c(curtosis),
 "Outliers" = rango_outliers)

# Generar Tabla GT
tabla_conclusiones_gt <- tabla_indicadores %>%
 gt() %>%
 tab_header(title = md("**Tabla N°3 de Conclusiones de Área de las Plantas Solares**")) %>%
 tab_source_note(source_note = "Autor: Martin Sarmiento") %>%
 cols_label(
  Variable = "Variable",
  Rango_MinMax = "Rango",
  X = "Media (X)",
  Me = "Mediana (Me)",
  Mo = "Moda (Mo)",
  V = "Varianza (V)",
  Sd = "Desv. Est. (Sd)",
  Cv = "C.V. (%)",
  As = "Asimetría (As)",
  K = "Curtosis (K)",
  Outliers = "Outliers [Intervalo]"
 ) %>%
 tab_options(
  heading.title.font.size = px(16),
  column_labels.background.color = "#f0f0f0"
 )

tabla_conclusiones_gt
Tabla N°3 de Conclusiones de Área de las Plantas Solares
Variable Rango Media (X) Mediana (Me) Moda (Mo) Varianza (V) Desv. Est. (Sd) C.V. (%) Asimetría (As) Curtosis (K) Outliers [Intervalo]
Área (m²) [1; 17051000] 135645.5 2117.99 655810 328343546449 573012.7 422.43 12.47367 246.2795 913 [111119; 17051000]
Autor: Martin Sarmiento

6 Conclusiones

La variable “Área” fluctúa entre 1 y 17051000 m² y sus valores se encuentran alrededor de 2117.99 m², con una desviación estándar de 573012.7, siendo una variable muy heterogénea, cuyos valores se concentran en la parte media baja de la variable con la agregación de presencia de valores atípicos de 913 outliers; por todo lo anterior, el comportamiento de la variable es muy perjudicial.