Instalamos y cargamos el paquete tidyverse.
if (!require(tidyverse)) { install.packages(tidyverse); library(tidyverse) }
## Loading required package: tidyverse
## -- Attaching packages --------------------------- tidyverse 1.2.1 --
## v ggplot2 3.2.1 v purrr 0.3.2
## v tibble 2.1.3 v dplyr 0.8.3
## v tidyr 0.8.3 v stringr 1.4.0
## v readr 1.3.1 v forcats 0.4.0
## -- Conflicts ------------------------------ tidyverse_conflicts() --
## x dplyr::filter() masks stats::filter()
## x dplyr::lag() masks stats::lag()
Cargamos el conjunto de datos diamonds disponible en el paquete ggplot2.
library(ggplot2)
data <- ggplot2::diamonds
help("diamonds") # Obtenemos una descripción del conjunto de datos
## starting httpd help server ... done
str(data)
## Classes 'tbl_df', 'tbl' and 'data.frame': 53940 obs. of 10 variables:
## $ carat : num 0.23 0.21 0.23 0.29 0.31 0.24 0.24 0.26 0.22 0.23 ...
## $ cut : Ord.factor w/ 5 levels "Fair"<"Good"<..: 5 4 2 4 2 3 3 3 1 3 ...
## $ color : Ord.factor w/ 7 levels "D"<"E"<"F"<"G"<..: 2 2 2 6 7 7 6 5 2 5 ...
## $ clarity: Ord.factor w/ 8 levels "I1"<"SI2"<"SI1"<..: 2 3 5 4 2 6 7 3 4 5 ...
## $ depth : num 61.5 59.8 56.9 62.4 63.3 62.8 62.3 61.9 65.1 59.4 ...
## $ table : num 55 61 65 58 58 57 57 55 61 61 ...
## $ price : int 326 326 327 334 335 336 336 337 337 338 ...
## $ x : num 3.95 3.89 4.05 4.2 4.34 3.94 3.95 4.07 3.87 4 ...
## $ y : num 3.98 3.84 4.07 4.23 4.35 3.96 3.98 4.11 3.78 4.05 ...
## $ z : num 2.43 2.31 2.31 2.63 2.75 2.48 2.47 2.53 2.49 2.39 ...
El conjunto de datos tiene dimensión 53940x10. Recoge información sobre las siguientes variables:
price tipo int Precio del diamante en US$carat tipo num Peso del diamantecut tipo Ord.factor Calidad del talladocolor tipo Ord.factor Color del diamanteclarity tipo Ord.factor Medida de claridad del diamantex tipo num Longitud en mmy tipo num Anchura en mmz tipo num Profundidad en mmdepth tipo num Porcentaje de profundidad total. Es una medida derivada de x, y, z.table tipo num Ancho de la parte superior del diamante en relación con el punto más ancho.head(data, n=10) # Mostramos las 10 primeas filas del data.frame creado
## # A tibble: 10 x 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
## 4 0.290 Premium I VS2 62.4 58 334 4.2 4.23 2.63
## 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
## 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
## 7 0.24 Very Good I VVS1 62.3 57 336 3.95 3.98 2.47
## 8 0.26 Very Good H SI1 61.9 55 337 4.07 4.11 2.53
## 9 0.22 Fair E VS2 65.1 61 337 3.87 3.78 2.49
## 10 0.23 Very Good H VS1 59.4 61 338 4 4.05 2.39
Creamos el conjunto data_carat que contiene el precio máximo en función del peso de los diamantes (variable carat).
if (!require(dplyr)) { install.packages(dplyr); library(dplyr) }
data_carat <- data %>% group_by(carat) %>% summarize(PrecioMax=max(price))
head(data_carat, n=10)
## # A tibble: 10 x 2
## carat PrecioMax
## <dbl> <int>
## 1 0.2 367
## 2 0.21 394
## 3 0.22 470
## 4 0.23 688
## 5 0.24 963
## 6 0.25 1186
## 7 0.26 814
## 8 0.27 893
## 9 0.28 828
## 10 0.290 1776
Creamos el conjunto data_color que contiene el precio máximo en función del color de los diamantes (variable color). El color se ha codificado como factor ordenado con 7 niveles desde D(mejor) hasta J(peor).
if (!require(dplyr)) { install.packages(dplyr); library(dplyr) }
data_color <- data %>% group_by(color) %>% summarize(PrecioMax=max(price))
head(data_color, n=7) # El conjunto solo tiene 7 filas, una por cada nivel de color
## # A tibble: 7 x 2
## color PrecioMax
## <ord> <int>
## 1 D 18693
## 2 E 18731
## 3 F 18791
## 4 G 18818
## 5 H 18803
## 6 I 18823
## 7 J 18710
Creamos el conjunto data_cut que contiene el precio máximo en función de la calidad del tallado de los diamantes (variable cut). La calidad del tallado se ha codificado como factor ordenado con 5 niveles Fair, Good, Very Good, Premium, Ideal
if (!require(dplyr)) { install.packages(dplyr); library(dplyr) }
data_cut <- data %>% group_by(cut) %>% summarize(PrecioMax=max(price))
head(data_cut, n=5) # El conjunto solo tiene 5 filas, una por cada nivel de cut
## # A tibble: 5 x 2
## cut PrecioMax
## <ord> <int>
## 1 Fair 18574
## 2 Good 18788
## 3 Very Good 18818
## 4 Premium 18823
## 5 Ideal 18806
Creamos el conjunto data_clarity que contiene el precio máximo en función de la claridad de los diamantes (variable clarity). La claridad se ha codificado como factor ordenado con 8 niveles I1(peor), SI2, SI1, VS2, VS1, VVS2, VVS1, IF(mejor).
if (!require(dplyr)) { install.packages(dplyr); library(dplyr) }
data_clarity <- data %>% group_by(clarity) %>% summarize(PrecioMax=max(price))
head(data_clarity, n=8) # El conjunto solo tiene 8 filas, una por cada nivel de clarity
## # A tibble: 8 x 2
## clarity PrecioMax
## <ord> <int>
## 1 I1 18531
## 2 SI2 18804
## 3 SI1 18818
## 4 VS2 18823
## 5 VS1 18795
## 6 VVS2 18768
## 7 VVS1 18777
## 8 IF 18806
Creamos el conjunto data_ca_co que contiene el precio máximo en función del peso y el color de los diamantes (variables carat y color).
if (!require(dplyr)) { install.packages(dplyr); library(dplyr) }
data_ca_co <- data %>% group_by(carat, color) %>% summarize(PrecioMax=max(price))
head(data_ca_co, n=10)
## # A tibble: 10 x 3
## # Groups: carat [4]
## carat color PrecioMax
## <dbl> <ord> <int>
## 1 0.2 D 367
## 2 0.2 E 367
## 3 0.2 F 367
## 4 0.21 D 386
## 5 0.21 E 394
## 6 0.22 D 404
## 7 0.22 E 404
## 8 0.22 F 470
## 9 0.23 D 688
## 10 0.23 E 682
Creamos el conjunto data_ca_cu que contiene el precio máximo en función del peso y el tallado de los diamantes (variables carat y cut).
if (!require(dplyr)) { install.packages(dplyr); library(dplyr) }
data_ca_cu <- data %>% group_by(carat, cut) %>% summarize(PrecioMax=max(price))
head(data_ca_cu, n=10)
## # A tibble: 10 x 3
## # Groups: carat [4]
## carat cut PrecioMax
## <dbl> <ord> <int>
## 1 0.2 Very Good 367
## 2 0.2 Premium 367
## 3 0.2 Ideal 367
## 4 0.21 Very Good 386
## 5 0.21 Premium 394
## 6 0.22 Fair 337
## 7 0.22 Premium 470
## 8 0.23 Fair 369
## 9 0.23 Good 537
## 10 0.23 Very Good 682
Creamos el conjunto data_ca_cla que contiene el precio máximo en función del peso y la claridad de los diamantes (variables carat y clarity).
if (!require(dplyr)) { install.packages(dplyr); library(dplyr) }
data_ca_cla <- data %>% group_by(carat, clarity) %>% summarize(PrecioMax=max(price))
head(data_ca_cla, n=10)
## # A tibble: 10 x 3
## # Groups: carat [4]
## carat clarity PrecioMax
## <dbl> <ord> <int>
## 1 0.2 SI2 345
## 2 0.2 VS2 367
## 3 0.21 SI2 394
## 4 0.21 SI1 326
## 5 0.21 VS2 386
## 6 0.22 SI1 470
## 7 0.22 VS2 404
## 8 0.23 SI2 449
## 9 0.23 SI1 375
## 10 0.23 VS2 577
price ~ caratlibrary(ggplot2)
ggplot(data, aes(carat, price)) +
geom_point()
Parece haber una relación positiva entre el precio y el peso del diamante. Puede intuirse una relación no lineal y se aprecia un aumento de la dispersión en el precio cuando crece el peso de los diamantes.
En el siguiente gráfico modificamos el anterior para que los puntos tengan un color distinto según la calidad del tallado del diamante (niveles de cut).
library(ggplot2)
ggplot(data, aes(carat, price, colour=cut)) +
geom_point()
Las distintas categorías de cut quedan muy solapadas, lo que dificulta la interpretación del gráfico. Sin embargo, sí se puede apreciar que los diamantes con tallado Ideal (el mejor) se sitúan en la franja alta de la nube de puntos (mayor precio para un peso dado), mientras que aquellos con tallado Fair (el peor) se encuentran en la franja baja de la nube de puntos (menor precio para un peso dado).
En el siguiente gráfico separamos el gráfico anterior en cinco nubes de puntos, una para cada categoría de cut. La relación entre precio y peso parece de tipo exponencial positiva independientemente de la calidad del tallado. La calidad de tallado Fair parece mostrar mayor heteroscedasticidad en el precio a medida que el peso del diamante aumenta.
library(ggplot2)
ggplot(data, aes(carat, price, colour=cut)) +
geom_point() +
facet_grid(cols=vars(cut))
El último gráfico de puntos recoge la relación entre precio y peso de los diamantes separando las nubes de puntos según los grupos formados con las categorías de calidad del tallado y color.
La influencia del color sobre la relación entre precio y peso es similar para las distintas calidades del tallado: un mejor color intensifica el grado de relación entre precio y peso. Dicho de otro modo, entre los diamantes con mejor color el aumento del precio ante un aumento del peso es mayor que entre los diamantes con peor color.
library(ggplot2)
ggplot(data, aes(carat, price, colour=cut)) +
geom_point() +
facet_grid(rows=vars(color), cols=vars(cut))
price ~ cutlibrary(ggplot2)
ggplot(data, aes(cut, price)) +
geom_boxplot()
Observando el gráfico anterior vemos que la distribución del precio en función de la calidad del tallado es similar para todas las calidades. Los valores de la mediana son muy parecidos salvo para Ideal, donde es algo menor. La categoría Premium presenta una mayor dispersión (con un rango intercuartílico algo mayor). Todas las distribuciones presentan asimetría positiva o hacia la derecha. Además, es en los valores más altos para el precio donde aparecen los outliers de todas las distribuciones.
price ~ colorlibrary(ggplot2)
ggplot(data, aes(color, price)) +
geom_boxplot()
Del gráfico anterior podemos deducir que las distribuciones del precio según el color presentan mayor variabilidad en la medida en que éste empeora. Además, el precio mediano es mayor entre los diamantes con peor color.1 Al igual que en el diagrama de caja según la calidad del tallado, en este caso todas las distribuciones son asimétricas positivas y presentan outliers en la cola derecha de la distribución.
i. ¿Es lineal la relación entre price con respecto a cut y color?
Existe dependencia lineal con ambos factores. Si consideramos la relación entre price y carat se observa en los gráficos de puntos que ésta cambia tanto en función de cut como en función de color. En mi opinión, lo más destacable en cuanto a la influencia de cut es el aumento de heteroscedasticidad en el precio en función de carat cuando consideramos categorías con peor calidad del tallado. En cuanto a la influencia de color, el grado de la relación precio/peso se hace más fuerte entre las categorías con mejor color respecto a las de peor color.
ii. ¿Dirías que hay outliers en alguna de las combinaciones? Razona tu respuesta.
Atendiendo a los boxplots que hemos realizado observamos que hay outliers entre los precios altos tanto para los grupos formados por cut como para los formados por color.
iii. Para describir matemáticamente la relación entre price y las variables cuty color, ¿qué tipo de modelo aplicarías entonces? Razona tu respuesta.
Empezaría por ajustar un modelo de regresión lineal múltiple para price en función de carat y de un conjunto de variables ficticias o dummies construidas para los factores cut y color.
Nota para el profesor: Me han sorprendido los resultados obtenidos en los diagramas de caja. En el primer gráfico el precio mediano más bajo es el de la categoría con mejor calidad de tallado (Fair) y en el segundo el precio mediano más bajo es el de la categoría con mejor color (D). ¿No son estos resultados contraintuitivos? ¿Hay algo que no esté considerando o se trata de algún error en mi código? Le agradecería si pudiera responderme estas cuestiones en los comentarios de su evaluación.↩