1 Paso 1 — Carga de datos y exploración de la estructura

# El dataset diamonds viene incluido en ggplot2 (parte de tidyverse)
data(diamonds)

1.1 Vista preliminar de los datos

head(diamonds, 10) %>%
  kable(caption = "Primeras 10 observaciones del dataset diamonds") %>%
  estilo_tabla()
Primeras 10 observaciones del dataset diamonds
carat cut color clarity depth table price x y z
0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
0.29 Premium I VS2 62.4 58 334 4.20 4.23 2.63
0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
0.23 Very Good H VS1 59.4 61 338 4.00 4.05 2.39

1.2 Estructura del dataset

glimpse(diamonds)
## Rows: 53,940
## Columns: 10
## $ carat   <dbl> 0.23, 0.21, 0.23, 0.29, 0.31, 0.24, 0.24, 0.26, 0.22, 0.23, 0.…
## $ cut     <ord> Ideal, Premium, Good, Premium, Good, Very Good, Very Good, Ver…
## $ color   <ord> E, E, E, I, J, J, I, H, E, H, J, J, F, J, E, E, I, J, J, J, I,…
## $ clarity <ord> SI2, SI1, VS1, VS2, SI2, VVS2, VVS1, SI1, VS2, VS1, SI1, VS1, …
## $ depth   <dbl> 61.5, 59.8, 56.9, 62.4, 63.3, 62.8, 62.3, 61.9, 65.1, 59.4, 64…
## $ table   <dbl> 55, 61, 65, 58, 58, 57, 57, 55, 61, 61, 55, 56, 61, 54, 62, 58…
## $ price   <int> 326, 326, 327, 334, 335, 336, 336, 337, 337, 338, 339, 340, 34…
## $ x       <dbl> 3.95, 3.89, 4.05, 4.20, 4.34, 3.94, 3.95, 4.07, 3.87, 4.00, 4.…
## $ y       <dbl> 3.98, 3.84, 4.07, 4.23, 4.35, 3.96, 3.98, 4.11, 3.78, 4.05, 4.…
## $ z       <dbl> 2.43, 2.31, 2.31, 2.63, 2.75, 2.48, 2.47, 2.53, 2.49, 2.39, 2.…

El dataset contiene 53,940 observaciones y 10 variables.

1.2.1 Tipos de variables

Selección de variables:

Variable Tipo Descripción
price Numérica discreta Precio del diamante (USD)
carat Numérica continua Peso del diamante (quilates)
cut Categórica ordinal Calidad del corte (Fair → Ideal)
color Categórica ordinal Color (J peor → D mejor)
clarity Categórica ordinal Pureza (I1 peor → IF mejor)

1.3 Rango de precios

diamonds %>%
  summarise(
    minimo  = min(price),
    Q1      = quantile(price, 0.25),
    mediana = median(price),
    media   = mean(price),
    Q3      = quantile(price, 0.75),
    maximo  = max(price)
  ) %>%
  kable(digits = 0, caption = "Estadísticos del precio (USD)") %>%
  estilo_tabla()
Estadísticos del precio (USD)
minimo Q1 mediana media Q3 maximo
326 950 2401 3933 5324 18823

El precio de los diamantes va desde $326 hasta $18,823 USD. La media ($3,933) es notablemente mayor que la mediana ($2,401), lo que adelanta una distribución asimétrica con cola larga hacia precios altos — característica del mercado de bienes de lujo.


2 Paso 2 — Evaluación de la calidad de los datos

2.1 Valores faltantes (NA)

diamonds %>%
  summarise(across(everything(), ~ sum(is.na(.)))) %>%
  pivot_longer(everything(), names_to = "variable", values_to = "n_NA") %>%
  kable(caption = "Conteo de valores faltantes por variable") %>%
  estilo_tabla()
Conteo de valores faltantes por variable
variable n_NA
carat 0
cut 0
color 0
clarity 0
depth 0
table 0
price 0
x 0
y 0
z 0

El dataset no presenta valores faltantes en ninguna variable. No es necesario aplicar imputación ni eliminación de registros por NAs.

2.2 Valores no válidos (negativos o ceros)

En diamantes reales, ni el peso ni el precio pueden ser negativos o cero, y las dimensiones físicas (x, y, z) no pueden ser cero (un diamante con dimensión nula no existe).

diamonds %>%
  summarise(
    carat_no_positivo = sum(carat <= 0),
    price_no_positivo = sum(price <= 0),
    x_cero = sum(x == 0),
    y_cero = sum(y == 0),
    z_cero = sum(z == 0)
  ) %>%
  pivot_longer(everything(), names_to = "verificacion", values_to = "n_registros") %>%
  kable(caption = "Verificación de valores no válidos") %>%
  estilo_tabla()
Verificación de valores no válidos
verificacion n_registros
carat_no_positivo 0
price_no_positivo 0
x_cero 8
y_cero 7
z_cero 20

Hallazgo: carat y price no presentan valores no válidos, pero las dimensiones físicas sí: existen registros con x = 0, y = 0 y z = 0. Aunque estas variables no se analizan en esta actividad, su presencia sugiere errores de medición en el origen de los datos.

2.3 Registros duplicados

n_duplicados <- sum(duplicated(diamonds))

tibble(
  filas_totales    = nrow(diamonds),
  filas_unicas     = nrow(diamonds) - n_duplicados,
  filas_duplicadas = n_duplicados,
  pct_duplicados   = round(100 * n_duplicados / nrow(diamonds), 2)
) %>%
  kable(caption = "Análisis de duplicados") %>%
  estilo_tabla()
Análisis de duplicados
filas_totales filas_unicas filas_duplicadas pct_duplicados
53940 53794 146 0.27

Se detectan 146 filas duplicadas. Como el dataset no incluye un identificador único por pieza, no es posible distinguir si corresponden a diamantes distintos con características idénticas (plausible, dado el redondeo de las variables) o a errores reales de duplicación.

2.4 Outliers en variables numéricas (price y carat)

diamonds %>%
  select(carat, price) %>%
  pivot_longer(everything(), names_to = "variable", values_to = "valor") %>%
  ggplot(aes(x = valor)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.5,
               outlier.alpha = 0.4) +
  facet_wrap(~ variable, scales = "free", ncol = 2) +
  labs(title = "Boxplots de las variables numéricas analizadas",
       x = NULL, y = NULL) +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        axis.text.y = element_blank(),
        axis.ticks.y = element_blank())

Ambas variables presentan outliers en el extremo superior, pero no parecen errores: son valores plausibles de un mercado donde coexisten diamantes pequeños y baratos (mayoría) con piezas excepcionales grandes y caras (minoría).

2.5 Reflexión: ¿necesitamos limpiar los datos?

Conforme al enunciado, no se limpian los datos. Sin embargo, se documentan los hallazgos a tener en cuenta en futuros análisis:

  • No hay NAs — no requiere imputación.
  • Hay ceros inválidos en x, y, z — afectan análisis dimensionales pero no las cinco variables que se analizan en esta actividad.
  • Hay duplicados — podrían evaluarse según el algoritmo posterior (en KNN o clustering podrían sesgar resultados).
  • Los outliers de price y carat son valores reales del mercado y deben conservarse para no perder información sobre piezas premium.

3 Paso 3 — Análisis univariado

3.1 Variables numéricas — Boxplots

3.1.1 price (precio)

ggplot(diamonds, aes(x = price)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.6,
               outlier.alpha = 0.4) +
  labs(title = "Distribución del precio (USD)", x = "Precio (USD)", y = NULL) +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        axis.text.y = element_blank(), axis.ticks.y = element_blank())

Reflexión — price

  • Rango: de $326 a $18,823, pero el rango más frecuente (entre Q1 y Q3) está concentrado entre $950 y $5,300.
  • Valores extremos: a partir de aproximadamente $11,900 los registros son outliers estadísticos según la regla del IQR.
  • ¿Son reales? Sí. Corresponden a diamantes grandes con excelentes propiedades — son piezas premium reales, no errores.
  • ¿Refleja la oferta del mercado o hay sesgo? Refleja una oferta sesgada hacia el segmento minorista: la mayoría de los diamantes son de precio accesible, y faltan piezas de inversión (>$50,000) que existen en el mercado pero no en esta muestra.

3.1.2 carat (peso)

ggplot(diamonds, aes(x = carat)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.6,
               outlier.alpha = 0.4) +
  labs(title = "Distribución del peso (carat)", x = "Peso (carat)", y = NULL) +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        axis.text.y = element_blank(), axis.ticks.y = element_blank())

Reflexión — carat

  • Rango: de 0.20 a 5.01 quilates, con el rango más frecuente entre 0.40 y 1.04 ct (50% central).
  • Valores extremos: a partir de ~2 ct los registros son outliers, pero todos son valores reales.
  • ¿Refleja la oferta del mercado? Sí. Los diamantes grandes son geológicamente escasos, por lo que su baja frecuencia en la muestra refleja la realidad del mercado, no un sesgo.

3.2 Variables categóricas — Gráficos de barras

3.2.1 cut (calidad del corte)

diamonds %>%
  count(cut) %>%
  mutate(pct = round(100 * n / sum(n), 1)) %>%
  ggplot(aes(x = cut, y = n)) +
  geom_col(fill = "#2C3E50", width = 0.7) +
  geom_text(aes(label = paste0(format(n, big.mark = ","), " (", pct, "%)")),
            vjust = -0.3, size = 3.3, color = "#2C3E50") +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(title = "Distribución de la calidad del corte (cut)",
       x = NULL, y = "Frecuencia") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        panel.grid.major.x = element_blank())

Reflexión — cut

  • Categoría más común: Ideal (~40%), el corte de mayor calidad.
  • Categoría menos común: Fair (~3%), el corte de menor calidad.
  • ¿Esperaba esta distribución? Sí parcialmente. Cabría esperar más variedad, pero el dataset refleja una realidad comercial: los joyeros priorizan cortes de alta calidad porque tienen mayor rotación y margen.
  • ¿Refleja la oferta del mercado? Existe un sesgo de canal: los diamantes con cortes pobres rara vez llegan al mercado formal, lo que explica la sobre-representación de Ideal y Premium.

3.2.2 color (color)

diamonds %>%
  mutate(color = factor(color, levels = c("D","E","F","G","H","I","J"))) %>%
  count(color) %>%
  mutate(pct = round(100 * n / sum(n), 1)) %>%
  ggplot(aes(x = color, y = n)) +
  geom_col(fill = "#2C3E50", width = 0.7) +
  geom_text(aes(label = paste0(format(n, big.mark = ","), " (", pct, "%)")),
            vjust = -0.3, size = 3.3, color = "#2C3E50") +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(title = "Distribución del color (D = mejor → J = peor)",
       x = NULL, y = "Frecuencia") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        panel.grid.major.x = element_blank())

Reflexión — color

  • Categoría más común: G (~21%), color intermedio casi incoloro.
  • Categoría menos común: J (~5%), el color más amarillento.
  • La distribución es aproximadamente unimodal y centrada en colores intermedios (F, G, H), no en los extremos. Refleja una lógica de mercado: los colores intermedios son los más comercializados porque ofrecen el mejor balance apariencia/precio.

3.2.3 clarity (claridad)

diamonds %>%
  mutate(clarity = factor(clarity,
                          levels = c("I1","SI2","SI1","VS2","VS1","VVS2","VVS1","IF"))) %>%
  count(clarity) %>%
  mutate(pct = round(100 * n / sum(n), 1)) %>%
  ggplot(aes(x = clarity, y = n)) +
  geom_col(fill = "#2C3E50", width = 0.7) +
  geom_text(aes(label = paste0(format(n, big.mark = ","), " (", pct, "%)")),
            vjust = -0.3, size = 3.3, color = "#2C3E50") +
  scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
  labs(title = "Distribución de la claridad (I1 = peor → IF = mejor)",
       x = NULL, y = "Frecuencia") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        panel.grid.major.x = element_blank())

Reflexión — clarity

  • Categoría más común: SI1 (~24%), claridad media con pequeñas inclusiones visibles solo con lupa.
  • Categoría menos común: I1 (~1.4%), claridad pobre con inclusiones visibles a simple vista.
  • ¿Esperaba esta distribución? Sí. Los extremos son raros por motivos distintos: los diamantes perfectamente limpios (IF) son geológicamente raros, mientras que los muy incluidos (I1) se descartan o se reservan para uso industrial. La muestra refleja el segmento de joyería formal.

4 Paso 4 — Relación entre precio y peso (análisis bivariado)

4.1 Gráfico de dispersión carat vs price

ggplot(diamonds, aes(x = carat, y = price)) +
  geom_point(alpha = 0.15, color = "#2C3E50", size = 0.6) +
  geom_smooth(method = "loess", color = "coral", se = FALSE, linewidth = 1) +
  labs(title = "Relación entre peso (carat) y precio (USD)",
       subtitle = "53,940 observaciones · Curva suavizada en coral",
       x = "Peso (carat)", y = "Precio (USD)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

4.2 Reflexión sobre la relación carat–price

¿Cómo se relacionan?

Existe una relación positiva clara: a mayor peso, mayor precio.

¿Los diamantes más grandes son siempre más caros?

No. Para un mismo peso, los precios pueden variar enormemente: dos diamantes de ~1 ct pueden costar entre $2,000 y $18,000 dependiendo de las otras características (cut, color, clarity).

¿La relación es lineal o muestra crecimiento acelerado?

La curva suavizada muestra crecimiento acelerado, no lineal: el precio crece más rápido que el peso. Doblar el peso multiplica el precio por más del doble.

¿Hay umbrales psicológicos donde el precio se dispara?

Sí. Se observan bandas verticales densas en los pesos comerciales clásicos: 0.30, 0.50, 0.70, 1.00, 1.50 y 2.00 quilates. Los cortadores sacrifican peso real para alcanzar estos umbrales redondos porque el mercado los premia con saltos de precio. Por ejemplo, un diamante de 0.99 ct vale mucho menos que uno de 1.00 ct, aunque la diferencia visual sea imperceptible.

¿Por qué dos diamantes del mismo peso pueden tener precios muy distintos?

Porque el precio depende de las 4 C’s (carat, cut, color, clarity), no solo del peso. La dispersión vertical observada para cada valor de carat anticipa el análisis de los Pasos 5 y 6.


5 Paso 5 — Impacto de cut, clarity y color en el precio

5.1 Efecto del corte (cut)

ggplot(diamonds, aes(x = cut, y = price)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.4,
               outlier.alpha = 0.3) +
  stat_summary(fun = mean, geom = "point",
               shape = 23, size = 3, fill = "coral", color = "black") +
  labs(title = "Precio según calidad del corte (cut)",
       subtitle = "Diamante coral: precio medio del grupo",
       x = NULL, y = "Precio (USD)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

diamonds %>%
  group_by(cut) %>%
  summarise(
    n            = n(),
    precio_medio = round(mean(price), 0),
    carat_medio  = round(mean(carat), 2)
  ) %>%
  kable(caption = "Precio y peso medio por cut") %>%
  estilo_tabla()
Precio y peso medio por cut
cut n precio_medio carat_medio
Fair 1610 4359 1.05
Good 4906 3929 0.85
Very Good 12082 3982 0.81
Premium 13791 4584 0.89
Ideal 21551 3458 0.70

Reflexión — cut

Resultado contraintuitivo: el corte Ideal (mejor calidad) tiene el precio medio más bajo (~$3,458), mientras que el corte Premium tiene el más alto. Si el corte determinara el precio, esperaríamos lo contrario.

¿Por qué ocurre esto? Observando la columna carat_medio, los diamantes de corte Fair y Premium son considerablemente más pesados en promedio que los Ideal. Como el peso domina el precio, este efecto oculta la verdadera influencia del corte.

5.2 Efecto de la claridad (clarity)

diamonds %>%
  mutate(clarity = factor(clarity,
                          levels = c("I1","SI2","SI1","VS2","VS1","VVS2","VVS1","IF"))) %>%
  ggplot(aes(x = clarity, y = price)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.4,
               outlier.alpha = 0.3) +
  stat_summary(fun = mean, geom = "point",
               shape = 23, size = 3, fill = "coral", color = "black") +
  labs(title = "Precio según claridad",
       subtitle = "I1 = peor · IF = mejor · Diamante coral: precio medio",
       x = NULL, y = "Precio (USD)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

diamonds %>%
  mutate(clarity = factor(clarity,
                          levels = c("I1","SI2","SI1","VS2","VS1","VVS2","VVS1","IF"))) %>%
  group_by(clarity) %>%
  summarise(
    n            = n(),
    precio_medio = round(mean(price), 0),
    carat_medio  = round(mean(carat), 2)
  ) %>%
  kable(caption = "Precio y peso medio por clarity") %>%
  estilo_tabla()
Precio y peso medio por clarity
clarity n precio_medio carat_medio
I1 741 3924 1.28
SI2 9194 5063 1.08
SI1 13065 3996 0.85
VS2 12258 3925 0.76
VS1 8171 3839 0.73
VVS2 5066 3284 0.60
VVS1 3655 2523 0.50
IF 1790 2865 0.51

Reflexión — clarity

Se repite el patrón paradójico: las claridades inferiores (I1, SI2) tienen precios medios superiores a las claridades excelentes (IF, VVS1). Si la claridad fuera el determinante principal del precio, los diamantes IF deberían ser los más caros.

¿Por qué? Los diamantes de baja claridad tienden a ser considerablemente más grandes (I1 promedia 1.28 ct, IF apenas 0.50 ct). De nuevo, el peso enmascara el efecto de la claridad.

5.3 Efecto del color

diamonds %>%
  mutate(color = factor(color, levels = c("D","E","F","G","H","I","J"))) %>%
  ggplot(aes(x = color, y = price)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.4,
               outlier.alpha = 0.3) +
  stat_summary(fun = mean, geom = "point",
               shape = 23, size = 3, fill = "coral", color = "black") +
  labs(title = "Precio según color",
       subtitle = "D = mejor → J = peor · Diamante coral: precio medio",
       x = NULL, y = "Precio (USD)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

diamonds %>%
  group_by(color) %>%
  summarise(
    n            = n(),
    precio_medio = round(mean(price), 0),
    carat_medio  = round(mean(carat), 2)
  ) %>%
  kable(caption = "Precio y peso medio por color") %>%
  estilo_tabla()
Precio y peso medio por color
color n precio_medio carat_medio
D 6775 3170 0.66
E 9797 3077 0.66
F 9542 3725 0.74
G 11292 3999 0.77
H 8304 4487 0.91
I 5422 5092 1.03
J 2808 5324 1.16

Reflexión — color

Patrón idéntico: los diamantes color J (peor color, más amarillento) tienen precio medio mayor que los color D (mejor color, perfectamente incoloro). Los diamantes J pesan en promedio casi el doble que los D.

5.4 Reflexión global del Paso 5

¿Por qué los mejores en calidad no son siempre los más caros?

Porque existe una correlación inversa entre tamaño y calidad en la oferta del mercado: los diamantes grandes tienden a tener peor cut, peor clarity y peor color. Como el peso domina el precio, este patrón superpuesto produce la paradoja observada — los diamantes de peor calidad aparente son los más grandes y, por tanto, los más caros en promedio.

Para evaluar el efecto real de cut, clarity y color hay que controlar por el peso (Paso 6).

¿Qué variable parece tener mayor influencia?

A nivel agregado, carat (peso) domina ampliamente el precio. El efecto de cut, clarity y color queda oculto al no controlar por el peso. En el Paso 6 se desentraña su impacto real.


6 Paso 6 — Análisis multivariado: efecto conjunto

6.1 6.1 Carat y cut

6.1.1 Distribución de carat por categoría de cut

ggplot(diamonds, aes(x = cut, y = carat)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.4,
               outlier.alpha = 0.3) +
  stat_summary(fun = mean, geom = "point",
               shape = 23, size = 3, fill = "coral", color = "black") +
  labs(title = "Peso (carat) según calidad del corte",
       x = NULL, y = "Peso (carat)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

6.1.2 Relación carat vs price por categoría de cut

ggplot(diamonds, aes(x = carat, y = price, color = cut)) +
  geom_point(alpha = 0.2, size = 0.5) +
  geom_smooth(method = "loess", se = FALSE, linewidth = 0.9) +
  scale_color_brewer(palette = "Set1") +
  labs(title = "Carat vs price segmentado por cut",
       x = "Peso (carat)", y = "Precio (USD)", color = "Cut") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        legend.position = "bottom")

Reflexión — cut

  • ¿Los diamantes grandes tienen mejor o peor corte? Tienden a tener peores cortes. El peso medio de los Fair (1.05 ct) es ~50% mayor que el de los Ideal (0.70 ct). Los cortadores sacrifican calidad del corte para conservar peso comercial en piezas grandes.
  • ¿Cuánto más caro es un Ideal vs un Fair del mismo peso? En el scatter segmentado se observa que, para un mismo carat, los Ideal están consistentemente por encima de los Fair. La prima por mejor corte ronda el 15-25%.
  • ¿El precio aumenta de la misma forma para todos los cortes? Sí, las curvas crecen de forma paralela. El corte cambia el nivel del precio, pero no la velocidad a la que crece con el peso.

6.2 6.2 Carat y clarity

6.2.1 Distribución de carat por categoría de clarity

diamonds %>%
  mutate(clarity = factor(clarity,
                          levels = c("I1","SI2","SI1","VS2","VS1","VVS2","VVS1","IF"))) %>%
  ggplot(aes(x = clarity, y = carat)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.4,
               outlier.alpha = 0.3) +
  stat_summary(fun = mean, geom = "point",
               shape = 23, size = 3, fill = "coral", color = "black") +
  labs(title = "Peso (carat) según claridad",
       subtitle = "I1 = peor → IF = mejor",
       x = NULL, y = "Peso (carat)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

6.2.2 Relación carat vs price por categoría de clarity

diamonds %>%
  mutate(clarity = factor(clarity,
                          levels = c("I1","SI2","SI1","VS2","VS1","VVS2","VVS1","IF"))) %>%
  ggplot(aes(x = carat, y = price, color = clarity)) +
  geom_point(alpha = 0.15, size = 0.5) +
  geom_smooth(method = "loess", se = FALSE, linewidth = 0.9) +
  scale_color_brewer(palette = "RdYlGn") +
  labs(title = "Carat vs price segmentado por clarity",
       subtitle = "Verde = mejor claridad · Rojo = peor",
       x = "Peso (carat)", y = "Precio (USD)", color = "Clarity") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        legend.position = "bottom")

Reflexión — clarity

  • ¿Los diamantes grandes suelen tener peor claridad? Sí, fuertemente. El peso medio de los I1 (1.28 ct) es más del doble que el de los IF (0.50 ct). La razón es geológica: a mayor tamaño, mayor probabilidad de que el cristal capture inclusiones durante su formación.
  • ¿Cuánto más caro es un diamante de alta claridad vs uno de baja claridad del mismo carat? El efecto es muy fuerte. Para un mismo peso, un IF puede valer hasta 3-4 veces más que un I1.
  • ¿Cómo cambia la relación según claridad? Las curvas están claramente separadas en niveles, en orden perfecto desde I1 (más bajo) hasta IF (más alto). La claridad actúa como un multiplicador fuerte sobre el precio base que define el peso.

6.3 6.3 Carat y color

6.3.1 Distribución de carat por categoría de color

diamonds %>%
  mutate(color = factor(color, levels = c("D","E","F","G","H","I","J"))) %>%
  ggplot(aes(x = color, y = carat)) +
  geom_boxplot(fill = "#2C3E50", color = "black",
               outlier.color = "coral", outlier.size = 0.4,
               outlier.alpha = 0.3) +
  stat_summary(fun = mean, geom = "point",
               shape = 23, size = 3, fill = "coral", color = "black") +
  labs(title = "Peso (carat) según color",
       subtitle = "D = mejor → J = peor",
       x = NULL, y = "Peso (carat)") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"))

6.3.2 Relación carat vs price por categoría de color

diamonds %>%
  mutate(color = factor(color, levels = c("D","E","F","G","H","I","J"))) %>%
  ggplot(aes(x = carat, y = price, color = color)) +
  geom_point(alpha = 0.15, size = 0.5) +
  geom_smooth(method = "loess", se = FALSE, linewidth = 0.9) +
  scale_color_brewer(palette = "RdYlBu") +
  labs(title = "Carat vs price segmentado por color",
       subtitle = "Azul = mejor color · Rojo = peor",
       x = "Peso (carat)", y = "Precio (USD)", color = "Color") +
  theme_minimal(base_size = 11) +
  theme(plot.title = element_text(face = "bold"),
        legend.position = "bottom")

Reflexión — color

  • ¿Los diamantes grandes tienden a colores más bajos? Sí. El peso medio crece monótonamente desde D (0.66 ct) hasta J (1.16 ct). La razón es geológica: a mayor tamaño, mayor probabilidad de absorber elementos traza (como nitrógeno) que producen el matiz amarillo.
  • ¿El impacto del color en el precio es mayor en diamantes grandes? Sí. En piezas pequeñas la diferencia D-J apenas se nota, pero en piezas grandes (>1 ct) la diferencia de precio entre un D y un J del mismo peso puede llegar a duplicarse. Esto refleja la lógica del mercado: a mayor inversión, mayor escrutinio sobre la pureza visual.
  • ¿Cómo varía el precio dentro de cada color y carat? Existe dispersión residual atribuible a las dos C’s restantes (cut y clarity), lo que confirma que el precio depende de la combinación de las 4 C’s.

7 Conclusiónes

¿Por qué los diamantes de mejor calidad no siempre son los más caros?

El análisis exploratorio muestra que la respuesta está en la interacción entre tamaño y calidad dentro de la oferta del mercado:

  1. El peso (carat) es el principal determinante del precio, con un crecimiento acelerado y no lineal.
  2. Existe una correlación inversa entre tamaño y calidad: los diamantes grandes tienden a tener peor cut, peor clarity y peor color, por razones geológicas (mayor probabilidad de inclusiones y trazas al crecer el cristal) y económicas (los cortadores sacrifican calidad de corte para conservar peso comercial).
  3. Cuando se analizan las variables de calidad de forma aislada, su efecto aparente queda invertido: los diamantes mejor cortados, más claros o más incoloros parecen más baratos, porque suelen ser más pequeños.
  4. Solo al controlar por peso (análisis multivariado del Paso 6) se revela el efecto real de cada característica: dentro de un mismo rango de peso, mejor calidad sí implica mayor precio, y el efecto más fuerte es el de la claridad, seguido del color y, en menor medida, el cut.

Implicaciones para futuros análisis: el dataset diamonds es un caso didáctico ideal para introducir el concepto de variable confusora (el peso enmascara el efecto de las otras variables) y para motivar el uso de modelos multivariados. La relación carat-price exhibe propiedades multiplicativas que justifican transformaciones logarítmicas en análisis predictivos posteriores.