1. Introducción

El presente trabajo tiene como objetivo aplicar técnicas de análisis exploratorio de datos (EDA) utilizando el lenguaje de programación R, con el propósito de identificar relaciones entre variables y analizar un conjunto de datos para detectar patrones de distribución, valores atípicos (outliers) y posibles anomalías.

Se utiliza la base de datos Wine Quality (vino tinto), la cual contiene 1,599 observaciones y 12 variables.

BD <- read.csv("C:/Users/artur/OneDrive/Escritorio/Data/winequality-red.csv")
# estructura de la base de datos
str(BD)
## 'data.frame':    1599 obs. of  12 variables:
##  $ fixed.acidity       : num  7.4 7.8 7.8 11.2 7.4 7.4 7.9 7.3 7.8 7.5 ...
##  $ volatile.acidity    : num  0.7 0.88 0.76 0.28 0.7 0.66 0.6 0.65 0.58 0.5 ...
##  $ citric.acid         : num  0 0 0.04 0.56 0 0 0.06 0 0.02 0.36 ...
##  $ residual.sugar      : num  1.9 2.6 2.3 1.9 1.9 1.8 1.6 1.2 2 6.1 ...
##  $ chlorides           : num  0.076 0.098 0.092 0.075 0.076 0.075 0.069 0.065 0.073 0.071 ...
##  $ free.sulfur.dioxide : num  11 25 15 17 11 13 15 15 9 17 ...
##  $ total.sulfur.dioxide: num  34 67 54 60 34 40 59 21 18 102 ...
##  $ density             : num  0.998 0.997 0.997 0.998 0.998 ...
##  $ pH                  : num  3.51 3.2 3.26 3.16 3.51 3.51 3.3 3.39 3.36 3.35 ...
##  $ sulphates           : num  0.56 0.68 0.65 0.58 0.56 0.56 0.46 0.47 0.57 0.8 ...
##  $ alcohol             : num  9.4 9.8 9.8 9.8 9.4 9.4 9.4 10 9.5 10.5 ...
##  $ quality             : int  5 5 5 6 5 5 5 7 7 5 ...

Interpretación: la base de datos está compuesta por 1,599 filas (vinos) y 12 columnas, todas de tipo numérico. Al no existir variables de tipo texto o factor, todo el análisis visual se realizará con boxplots e histogramas.

# resumen estadístico de la base de datos
summary(BD)
##  fixed.acidity   volatile.acidity  citric.acid    residual.sugar  
##  Min.   : 4.60   Min.   :0.1200   Min.   :0.000   Min.   : 0.900  
##  1st Qu.: 7.10   1st Qu.:0.3900   1st Qu.:0.090   1st Qu.: 1.900  
##  Median : 7.90   Median :0.5200   Median :0.260   Median : 2.200  
##  Mean   : 8.32   Mean   :0.5278   Mean   :0.271   Mean   : 2.539  
##  3rd Qu.: 9.20   3rd Qu.:0.6400   3rd Qu.:0.420   3rd Qu.: 2.600  
##  Max.   :15.90   Max.   :1.5800   Max.   :1.000   Max.   :15.500  
##    chlorides       free.sulfur.dioxide total.sulfur.dioxide    density      
##  Min.   :0.01200   Min.   : 1.00       Min.   :  6.00       Min.   :0.9901  
##  1st Qu.:0.07000   1st Qu.: 7.00       1st Qu.: 22.00       1st Qu.:0.9956  
##  Median :0.07900   Median :14.00       Median : 38.00       Median :0.9968  
##  Mean   :0.08747   Mean   :15.87       Mean   : 46.47       Mean   :0.9967  
##  3rd Qu.:0.09000   3rd Qu.:21.00       3rd Qu.: 62.00       3rd Qu.:0.9978  
##  Max.   :0.61100   Max.   :72.00       Max.   :289.00       Max.   :1.0037  
##        pH          sulphates         alcohol         quality     
##  Min.   :2.740   Min.   :0.3300   Min.   : 8.40   Min.   :3.000  
##  1st Qu.:3.210   1st Qu.:0.5500   1st Qu.: 9.50   1st Qu.:5.000  
##  Median :3.310   Median :0.6200   Median :10.20   Median :6.000  
##  Mean   :3.311   Mean   :0.6581   Mean   :10.42   Mean   :5.636  
##  3rd Qu.:3.400   3rd Qu.:0.7300   3rd Qu.:11.10   3rd Qu.:6.000  
##  Max.   :4.010   Max.   :2.0000   Max.   :14.90   Max.   :8.000

Interpretación: el resumen estadístico permite un primer diagnóstico:

# nombre de cada atributo (se traducen al español para facilitar la lectura)
names(BD) <- c("acidez fija",
               "acidez volatil",
               "acido citrico",
               "azucar residual",
               "cloruros",
               "dioxido azufre lib.",
               "dioxido azufre tot",
               "densidad",
               "pH",
               "sulfatos",
               "alcohol",
               "calidad")

2. Análisis visual del comportamiento de cada atributo

Se usó una estructura for como bucle iterativo para recorrer cada columna (atributo) de la base de datos y automatizar la generación de boxplots e histogramas. Las variables numéricas se dividieron en dos bloques de 6 para que los gráficos sean legibles.

BDN <- NULL
BDC <- NULL
columnas <- dim(BD)[2]
nombres_col <- colnames(BD)

# Primero identificamos qué columnas son numéricas y cuáles categóricas
for (i in 1:columnas) {
  if (is.numeric(BD[ ,i]) == TRUE) {
    BDN <- c(BDN, i)
  } else {
    BDC <- c(BDC, i)
  }
}

# ===== BLOQUE 1: primeras 6 variables numéricas =====
bloque1 <- BDN[1:6]

par(mfrow = c(2, 6), mar = c(4,4,3,1))

for (i in bloque1) {
  texto <- paste(nombres_col[i], "- Boxplot")
  boxplot(BD[ ,i],
          main = texto,
          col = i,
          cex.main = 0.9)
}

for (i in bloque1) {
  texto <- paste(nombres_col[i], "- Histograma")
  hist(BD[ ,i],
       main = texto,
       col = i,
       xlab = nombres_col[i],
       ylab = "frec",
       cex.main = 0.9)
}

Interpretación del Bloque 1 (acidez fija, acidez volátil, ácido cítrico, azúcar residual, cloruros, dióxido de azufre libre):

En conjunto, este bloque evidencia que las variables de composición química “traza” (azúcar, cloruros, SO₂ libre) son las que más outliers y asimetría presentan, mientras que la acidez (fija y volátil) es más estable.

# ===== BLOQUE 2: últimas 6 variables numéricas =====
bloque2 <- BDN[7:length(BDN)]

par(mfrow = c(2, length(bloque2)), mar = c(4,4,3,1))

for (i in bloque2) {
  texto <- paste(nombres_col[i], "- Box")
  boxplot(BD[ ,i],
          main = texto,
          col = i,
          cex.main = 0.9)
}

for (i in bloque2) {
  texto <- paste(nombres_col[i], "- Hist")
  hist(BD[ ,i],
       main = texto,
       col = i,
       xlab = nombres_col[i],
       ylab = "frec",
       cex.main = 0.9)
}

Interpretación del Bloque 2 (dióxido de azufre total, densidad, pH, sulfatos, alcohol, calidad):

# ===== CATEGÓRICAS (pie charts), si las hay =====
if (length(BDC) > 0) {
  par(mfrow = c(1, length(BDC)), mar = c(4,4,3,1))
  for (i in BDC) {
    texto <- paste(nombres_col[i])
    pie(table(BD[ ,i]),
        main = texto)
  }
} else {
  cat("No se generan gráficos de torta: las 12 variables de la base de datos son numéricas, no existen variables categóricas.")
}
## No se generan gráficos de torta: las 12 variables de la base de datos son numéricas, no existen variables categóricas.
## 
analizar_columna <- function(df, col_name) {
  variable <- df[[col_name]]
  nombre <- col_name
  cat("ANÁLISIS EXPLORATORIO PARA:", toupper(nombre), "\n")

  print(summary(variable))

  media <- mean(variable, na.rm = TRUE)
  desv <- sd(variable, na.rm = TRUE)

  cat("\nMedia:", media, "\n")
  cat("Desviación estándar:", desv, "\n")

  
  par(mfrow = c(1, 3))

  hist(variable,
        main = paste("Histograma:", nombre),
        xlab = nombre,
        ylab = "Frecuencia",
        col = "lightblue",
        border = "white")

  boxplot(variable,
          main = paste("Boxplot:", nombre),
          ylab = nombre,
          col = "lightpink")

  x <- seq(min(variable, na.rm = TRUE),
            max(variable, na.rm = TRUE),
            length.out = 100)

  y <- dnorm(x, mean = media, sd = desv)

  plot(x, y,
        type = "l",
        main = paste("Densidad Normal:", nombre),
        xlab = nombre,
        ylab = "Densidad")

  par(mfrow = c(1, 1))
}

analizar_columna(BD, "alcohol")
## ANÁLISIS EXPLORATORIO PARA: ALCOHOL 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    8.40    9.50   10.20   10.42   11.10   14.90 
## 
## Media: 10.42298 
## Desviación estándar: 1.065668

Interpretación del Análisis Exploratorio de la variable Alcohol:

Estadísticos Descriptivos:El nivel de alcohol presenta un promedio (media) de 10.42% con una desviación estándar de 1.07%. La mediana se ubica en 10.20%, oscilando entre un valor mínimo de 8.40% y un máximo de 14.90%.

Histograma y Distribución: Presenta una ligera asimetría positiva (sesgada hacia la derecha), mostrando que la mayor concentración de datos se encuentra en los valores bajos y medios de alcohol (entre 9.0% y 11.0%).

Boxplot (Valores Atípicos): Muestra una distribución relativamente limpia, con muy pocos valores atípicos (outliers) detectados por encima del bigote superior (vinos con graduación alcohólica superior a 13.5%).

Ajuste a la Curva Normal: La curva teórica refleja adecuadamente la densidad de probabilidad centrada cerca de la media, confirmando que la variable es continua y adecuada para el modelado estadístico.

Nota: este bloque confirma lo observado en str(BD) — al no existir variables categóricas, no se generan gráficos de torta. Este resultado es el esperado para este analisis exploratorio.

3. Conclusiones

A partir del análisis exploratorio realizado sobre las 1,599 observaciones del conjunto de datos de Wine Quality (vino tinto), se concluye lo siguiente:

  1. No existen variables categóricas en el analisis exploratorio; las 12 columnas son numéricas, por lo que el análisis solo se realizó en boxplots e histogramas.
  2. Azúcar residual, cloruros y sulfatos son las variables con mayor proporción de valores atípicos (outliers).
  3. Densidad y pH son las variables con distribución más simétrica y cercana a la normalidad, sin mayores anomalías. d)calidad variable objetiva, que está fuertemente concentrada en los puntajes 5 y 6.
  4. alcohol es el atributo fisicoquímico más asociado con la calidad del vino f)*acidez volátil** es el atributo más asociado con una menor calidad.