Proyecto estrictamente académico. Datos: EarthChem PetDB (CC BY 4.0), descargados el 13/10/2026. Web del proyecto: https://crisrumiguano-art.github.io/geoquimica-earthchem-ml/

1. Carga de datos y librerías

Se lee la base limpia (159 760 análisis de roca total × 75 variables). La primera vez se descarga del repositorio del proyecto (26 MB).

knitr::opts_chunk$set(
  echo = TRUE,          # muestra el código en el documento
  message = FALSE,      # sin mensajes de carga de paquetes
  warning = FALSE,      # sin advertencias
  fig.align = "center" # gráficos centrados
)
library(e1071)         # asimetría y curtosis (install.packages("e1071"))
if (!file.exists("data/earthchem_limpio.csv.gz")) {
  dir.create("data", showWarnings = FALSE)
  download.file("https://github.com/crisrumiguano-art/geoquimica-earthchem-ml/raw/main/data/earthchem_limpio.csv.gz",
                "data/earthchem_limpio.csv.gz", mode = "wb")
}
base <- read.csv(gzfile("data/earthchem_limpio.csv.gz", encoding = "UTF-8"), check.names = FALSE)
dim(base)              # filas y columnas
## [1] 159760     75

2. Datos

Se toma la columna de la variable y se quitan las filas vacías (vacío = no medido, nunca cero).

x <- base[["SiO2 Class"]]                         # la columna de la base
x <- as.character(x)                         # como texto
x <- x[!is.na(x) & x != ""]                  # quita los vacíos

3. Tabla de frecuencias

ni cuenta los casos de cada categoría y hi los expresa en porcentaje; la moda es la categoría con más casos.

orden <- c("ultrabasica", "basica", "intermedia", "acida")   # ordinal: su orden natural
conteo <- table(factor(x, levels = orden))   # cuenta cada categoría, en ese orden
categoria <- names(conteo)
ni <- as.vector(conteo)                      # frecuencia absoluta
hi <- round(ni / sum(ni) * 100, 2)           # frecuencia relativa (%)
Ni <- cumsum(ni)                             # acumulada absoluta (solo ordinales)
Hi <- round(cumsum(ni) / sum(ni) * 100, 2)   # acumulada relativa (%)
TDF <- data.frame(categoria, ni, hi, Ni, Hi)
knitr::kable(TDF, caption = "Tabla N° 1: distribución de frecuencias")
Tabla N° 1: distribución de frecuencias
categoria ni hi Ni Hi
ultrabasica 9389 16.46 9389 16.46
basica 29736 52.14 39125 68.60
intermedia 9171 16.08 48296 84.68
acida 8735 15.32 57031 100.00
categoria[which.max(ni)]                     # moda: la categoría con más casos
## [1] "basica"
categoria[which(Hi >= 50)[1]]                # mediana: donde Hi llega al 50 %
## [1] "basica"

4. Gráfico: barras + circular

Diagrama de barras (altura = ni) y diagrama circular (porción = hi).

par(mfrow = c(1, 2), mar = c(9, 5, 4, 1))    # 2 gráficos lado a lado
colores <- gray.colors(length(ni), start = .25, end = .85)       # un gris por categoría
barplot(ni, names.arg = categoria, las = 2, col = colores, ylab = "Cantidad",   # barras: altura = ni
        main = "Gráfica No. 5: Clase de roca según SiO2", cex.names = .8, cex.main = .9)
par(mar = c(1, 1, 4, 1))
pie(hi, labels = paste0(hi, "%"), col = colores, clockwise = TRUE, cex = .75,  # circular: porción = hi
    main = "Gráfica No. 6: Clase de roca según SiO2 (%)", cex.main = .9)
legend("topright", legend = categoria, fill = colores, cex = .6, bty = "n")

5. Conclusión

La categoría más frecuente (moda) es basica, con el 52,14 % de los 57 031 casos con dato, repartidos en 4 categorías. La mayoría de las rocas son básicas (45 a 52 % de SiO2), es decir basaltos y gabros, las rocas más comunes de la corteza oceánica. Al ser ordinal, la tabla lleva frecuencias acumuladas.