# ===============================================
#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>