# ===============================================
#UNIVERSIDAD CENTRAL DEL ECUADOR  
#Análisis Estadístico de la Variable Latitud en Sedimentos Marinos
# Grupo 3
#
# ===============================================

# Cargar librerías
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(kableExtra)
## 
## Attaching package: 'kableExtra'
## The following object is masked from 'package:dplyr':
## 
##     group_rows
if (!require("moments")) {
  install.packages("moments")
  library(moments)
} else {
  library(moments)
}
## Loading required package: moments
# Lectura y limpieza
setwd("/cloud/project")

datos <- read.csv("Sedimentos Marinos.csv",
                  header = TRUE,
                  sep = ";",
                  dec = ".",
                  stringsAsFactors = FALSE)

latitud_raw <- as.numeric(gsub("[^0-9.-]", "", datos$LATITUDE))
## Warning: NAs introduced by coercion
latitud <- latitud_raw
latitud <- latitud[latitud >= -90 & latitud <= 90]
latitud <- na.omit(latitud)

cat("Número de observaciones válidas (n):", length(latitud), "\n\n")
## Número de observaciones válidas (n): 536
# Intervalos múltiplos de 5
minimo <- min(latitud)
maximo <- max(latitud)
min_red <- floor(minimo / 5) * 5
max_red <- ceiling(maximo / 5) * 5
A <- 5

Li <- seq(min_red, max_red - A, by = A)
Ls <- seq(min_red + A, max_red, by = A)
MC <- (Li + Ls) / 2

# Frecuencias
ni <- numeric(length(Li))
for (i in 1:length(Li)) {
  if (i == length(Li)) {
    ni[i] <- sum(latitud >= Li[i])
  } else {
    ni[i] <- sum(latitud >= Li[i] & latitud < Ls[i])
  }
}

n <- length(latitud)

# Frecuencias relativas con 2 decimales
hi <- round((ni / n) * 100, 2)

# Corrección del error de redondeo (100.01 → 100.00)
error <- 100 - sum(hi)
if (abs(error) > 0) {
  hi[length(hi)] <- hi[length(hi)] + error
}

# Acumuladas
Ni_asc <- cumsum(ni)
Ni_dsc <- rev(cumsum(rev(ni)))
Hi_asc <- cumsum(hi)
Hi_dsc <- rev(cumsum(rev(hi)))

# Moda
moda_idx <- which.max(ni)
moda_intervalo <- paste(Li[moda_idx], "-", Ls[moda_idx])
moda_mc <- MC[moda_idx]

colores <- gray.colors(length(ni), start = 0.3, end = 0.9)
intervalos <- paste(Li, "-", Ls)

# === TABLA DE DISTRIBUCIÓN DE FRECUENCIAS ===
cat("\n")
cat("<h2 style='text-align:center; color:#2c3e50;'>Distribución de frecuencias de la variable latitud</h2>\n")
## <h2 style='text-align:center; color:#2c3e50;'>Distribución de frecuencias de la variable latitud</h2>
cat("<p style='text-align:center; font-style:italic; color:#7f8c8d;'>Autor: Grupo 3</p>\n")
## <p style='text-align:center; font-style:italic; color:#7f8c8d;'>Autor: Grupo 3</p>
cat("\n")
TDF <- data.frame(
  "Lím. Inf." = Li,
  "Lím. Sup." = Ls,
  "Marca Clase" = MC,
  "ni" = ni,
  "hi (%)" = paste0(format(round(hi, 2), nsmall = 2), " %"),
  "Ni asc" = Ni_asc,
  "Ni dsc" = Ni_dsc,
  "Hi asc (%)" = paste0(format(round(Hi_asc, 2), nsmall = 2), " %"),
  "Hi dsc (%)" = paste0(format(round(Hi_dsc, 2), nsmall = 2), " %")
)

# Fila total - SIN valores en Hi asc y Hi dsc
totales <- data.frame(
  "Lím. Inf." = "", "Lím. Sup." = "Total", "Marca Clase" = "",
  "ni" = n,
  "hi (%)" = "100.00 %",
  "Ni asc" = "",
  "Ni dsc" = "",
  "Hi asc (%)" = "",   # Vacío
  "Hi dsc (%)" = ""    # Vacío
)

TDF <- rbind(TDF, totales)

# Tabla con estilo bonito
TDF %>%
  kable("html", escape = FALSE, align = "c") %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
                full_width = FALSE, font_size = 14) %>%
  row_spec(0, bold = TRUE, color = "white", background = "#2c3e50") %>%
  row_spec(nrow(TDF), bold = TRUE, color = "white", background = "#27ae60")
Lím..Inf. Lím..Sup. Marca.Clase ni hi…. Ni.asc Ni.dsc Hi.asc…. Hi.dsc….
15 20 17.5 24 4.48 % 24 536 4.48 % 100.00 %
20 25 22.5 0 0.00 % 24 512 4.48 % 95.52 %
25 30 27.5 207 38.62 % 231 512 43.10 % 95.52 %
30 35 32.5 3 0.56 % 234 305 43.66 % 56.90 %
35 40 37.5 7 1.31 % 241 302 44.97 % 56.34 %
40 45 42.5 286 53.36 % 527 295 98.33 % 55.03 %
45 50 47.5 9 1.67 % 536 9 100.00 % 1.67 %
Total 536 100.00 %
cat("\n\n")
# === GRÁFICAS ===
cat("Generando gráficas...\n")
## Generando gráficas...
hist(latitud, breaks = c(Li, max_red), right = FALSE, col = colores,
     main = "Gráfica Nº2: Distribución absoluta local de la latitud",
     xlab = "Latitud (grados)", ylab = "Frecuencia absoluta")

hist(latitud, breaks = c(Li, max_red), right = FALSE, col = colores,
     main = "Gráfica Nº3: Distribución absoluta global de la latitud",
     xlab = "Latitud (grados)", ylab = "Frecuencia absoluta",
     ylim = c(0, n + 50))  # Llega a n con margen

barplot(hi, names.arg = intervalos, col = colores, space = 0, las = 2,
        main = "Gráfica Nº4: Distribución relativa local de la latitud",
        xlab = "Latitud (grados)", ylab = "Porcentaje (%)",
        ylim = c(0, max(hi) + 5))

barplot(hi, names.arg = intervalos, col = colores, space = 0, las = 2,
        main = "Gráfica Nº5: Distribución relativa global de la latitud",
        xlab = "Latitud (grados)", ylab = "Porcentaje (%)",
        ylim = c(0, 100))

plot(Ls, Ni_asc, type = "o", pch = 16, col = "blue",
     main = "Ojiva de frecuencias absolutas acumuladas",
     xlab = "Latitud (grados)", ylab = "Frecuencia absoluta acumulada")
lines(Ls, Ni_dsc, type = "o", pch = 16, col = "red")
legend("topleft", legend = c("Ascendente", "Descendente"), col = c("blue", "red"), pch = 16)

plot(Ls, cumsum(hi), type = "o", pch = 16, col = "blue",
     main = "Ojiva de frecuencias relativas acumuladas",
     xlab = "Latitud (grados)", ylab = "Frecuencia relativa acumulada (%)",
     ylim = c(0, 105))
lines(Ls, rev(cumsum(rev(hi))), type = "o", pch = 16, col = "red")
legend("bottomright", legend = c("Ascendente", "Descendente"), col = c("blue", "red"), pch = 16)

boxplot(latitud, horizontal = TRUE, col = "lightblue", border = "darkblue",
        main = "Diagrama de caja y bigotes - Latitud",
        xlab = "Latitud (grados)")

# === RESUMEN DE INDICADORES ESTADÍSTICOS ===
cat("\n\n=== RESUMEN DE INDICADORES ESTADÍSTICOS ===\n\n")
## 
## 
## === RESUMEN DE INDICADORES ESTADÍSTICOS ===
coef_var_raw <- (sd(latitud) / mean(latitud)) * 100
coef_var <- round(coef_var_raw, 2)

resumen_stats <- data.frame(
  Indicador = c("Mínimo", "Máximo", "Rango", "Media", "Mediana", "Moda (clase modal)", "Q1", "Q3",
                "Varianza", "Desv. estándar", "Coef. variación", "Asimetría", "Curtosis"),
  Símbolo = c("min", "max", "R", "x̄", "x̃", "-", "Q₁", "Q₃", "σ²", "σ", "CV", "γ", "κ"),
  Valor = c(round(minimo, 2), round(maximo, 2), round(maximo - minimo, 2),
            round(mean(latitud), 2), round(median(latitud), 2),
            paste(moda_intervalo, "(MC =", round(moda_mc, 2), ")"),
            round(quantile(latitud, 0.25), 2), round(quantile(latitud, 0.75), 2),
            round(var(latitud), 2), round(sd(latitud), 2),
            paste0(coef_var, " %"),
            round(skewness(latitud), 2), round(kurtosis(latitud), 2))
)

print(resumen_stats, row.names = FALSE)
##           Indicador Símbolo                Valor
##              Mínimo     min                18.12
##              Máximo     max                46.82
##               Rango       R                28.69
##               Media       x̄                 35.6
##             Mediana       x̃                40.56
##  Moda (clase modal)       - 40 - 45 (MC = 42.5 )
##                  Q1      Q₁                   28
##                  Q3      Q₃                42.39
##            Varianza      σ²                62.69
##      Desv. estándar       σ                 7.92
##     Coef. variación      CV              22.24 %
##           Asimetría       γ                -0.43
##            Curtosis       κ                 1.76
# === DETECCIÓN DE OUTLIERS ===
q1 <- quantile(latitud, 0.25)
q3 <- quantile(latitud, 0.75)
IQR_val <- q3 - q1
lim_inf <- q1 - 1.5 * IQR_val
lim_sup <- q3 + 1.5 * IQR_val
outliers <- latitud[latitud < lim_inf | latitud > lim_sup]

cat("\n=== DETECCIÓN DE VALORES ATÍPICOS (regla 1.5 × IQR) ===\n")
## 
## === DETECCIÓN DE VALORES ATÍPICOS (regla 1.5 × IQR) ===
cat("Límite inferior:", round(lim_inf, 2), "°\n")
## Límite inferior: 6.41 °
cat("Límite superior:", round(lim_sup, 2), "°\n")
## Límite superior: 63.98 °
cat("Cantidad de valores atípicos:", length(outliers), "\n")
## Cantidad de valores atípicos: 0
if (length(outliers) > 0) {
  cat("Rango de outliers:", round(min(outliers), 2), "° a", round(max(outliers), 2), "°\n")
} else {
  cat("No se detectaron valores atípicos.\n")
}
## No se detectaron valores atípicos.
# === CONCLUSIÓN DEL ANÁLISIS ===
cat("\n\n<h2 style='text-align:center; color:#2c3e50;'>Conclusión</h2>\n")
## 
## 
## <h2 style='text-align:center; color:#2c3e50;'>Conclusión</h2>
cat("<p style='text-align:justify; font-size:16px; line-height:1.6;'>\n")
## <p style='text-align:justify; font-size:16px; line-height:1.6;'>
cat("La variable Latitud fluctúa en torno al 40.56°, con una desviación estándar de 7.92°, lo que indica un conjunto de datos moderadamente homogéneos. ")
## La variable Latitud fluctúa en torno al 40.56°, con una desviación estándar de 7.92°, lo que indica un conjunto de datos moderadamente homogéneos.
cat("La distribución es ligeramente asimétrica negativa, es decir, sesgada hacia la izquierda, con la mayoría de los valores concentrados hacia la derecha (extremo superior). ")
## La distribución es ligeramente asimétrica negativa, es decir, sesgada hacia la izquierda, con la mayoría de los valores concentrados hacia la derecha (extremo superior).
cat("La concentración de los datos indica una forma platicúrtica .<br><br>\n")
## La concentración de los datos indica una forma platicúrtica .<br><br>
cat("No se detecta la presencia de outliers .<br><br>\n")
## No se detecta la presencia de outliers .<br><br>
cat("Por todo lo anterior, este comportamiento puede considerarse \"bueno\" desde un punto de vista estadístico clásico, pues la moderada dispersión, la casi simetría y la ausencia de outliers facilitan la aplicación de técnicas paramétricas, permiten generalizaciones más robustas y favorecen la construcción de modelos predictivos confiables.\n")
## Por todo lo anterior, este comportamiento puede considerarse "bueno" desde un punto de vista estadístico clásico, pues la moderada dispersión, la casi simetría y la ausencia de outliers facilitan la aplicación de técnicas paramétricas, permiten generalizaciones más robustas y favorecen la construcción de modelos predictivos confiables.
cat("</p>\n")
## </p>