LAB2 - Ejercicios y casos prácticos con R

Objetivos y enfoque

La finalidad de este documento es reproducir los ejercicios y casos prácticos contenidos en el apartado 12 del documento [1].

Para tener centralizado todo el trabajo se ha generado un proyecto y así fijar un directorio de trabajo que es el que contiene el fichero .Rproj.

[1] Casals, M. y Vila A. (2024). Estadística descriptiva y gráficos con R [Recurso de aprendizaje textual]. 1.a ed. Fundació Universitat Oberta de Catalunya (FUOC).

Ejercicio 1

El package de R datasets (https://stat.ethz.ch/R-manual/R-devel/library/datasets/html/00Index.html) pone a nuestra disposición una serie de conjuntos de datos con los que poder trabajar como, por ejemplo, iris, cars o Titanic. Escoged un conjunto de datos. Deberéis:

  • Buscar un resumen estadístico de las variables del dataset Iris y Orange.
library(datasets)
summary(Orange)
##  Tree       age         circumference  
##  3:7   Min.   : 118.0   Min.   : 30.0  
##  1:7   1st Qu.: 484.0   1st Qu.: 65.5  
##  5:7   Median :1004.0   Median :115.0  
##  2:7   Mean   : 922.1   Mean   :115.9  
##  4:7   3rd Qu.:1372.0   3rd Qu.:161.5  
##        Max.   :1582.0   Max.   :214.0
summary(iris)
##   Sepal.Length    Sepal.Width     Petal.Length    Petal.Width   
##  Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100  
##  1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300  
##  Median :5.800   Median :3.000   Median :4.350   Median :1.300  
##  Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199  
##  3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800  
##  Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500  
##        Species  
##  setosa    :50  
##  versicolor:50  
##  virginica :50  
##                 
##                 
## 
  • Generar una tabla de frecuencias absolutas y una tabla de frecuencias relativas con el dataset Iris. ¿Todas las tablas generadas tienen sentido para vosotros?
data(iris)
kable(table(iris$Sepal.Length))
Var1 Freq
4.3 1
4.4 3
4.5 1
4.6 4
4.7 2
4.8 5
4.9 6
5 10
5.1 9
5.2 4
5.3 1
5.4 6
5.5 7
5.6 6
5.7 8
5.8 7
5.9 3
6 6
6.1 6
6.2 4
6.3 9
6.4 7
6.5 5
6.6 2
6.7 8
6.8 3
6.9 4
7 1
7.1 1
7.2 3
7.3 1
7.4 1
7.6 1
7.7 4
7.9 1
table(iris$Sepal.Width)
## 
##   2 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9   3 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9   4 
##   1   3   4   3   8   5   9  14  10  26  11  13   6  12   6   4   3   6   2   1 
## 4.1 4.2 4.4 
##   1   1   1
table(iris$Petal.Length)
## 
##   1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.9   3 3.3 3.5 3.6 3.7 3.8 3.9   4 4.1 4.2 4.3 
##   1   1   2   7  13  13   7   4   2   1   2   2   1   1   1   3   5   3   4   2 
## 4.4 4.5 4.6 4.7 4.8 4.9   5 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9   6 6.1 6.3 6.4 
##   4   8   3   5   4   5   4   8   2   2   2   3   6   3   3   2   2   3   1   1 
## 6.6 6.7 6.9 
##   1   2   1
table(iris$Petal.Width)
## 
## 0.1 0.2 0.3 0.4 0.5 0.6   1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9   2 2.1 2.2 2.3 
##   5  29   7   7   1   1   7   3   5  13   8  12   4   2  12   5   6   6   3   8 
## 2.4 2.5 
##   3   3
table(iris$Species)
## 
##     setosa versicolor  virginica 
##         50         50         50

La tablas de frecuencia absoluta tienen sentido para las variables categóricas con en Species pero no para las variables numéricas en canvio las tablas de frecuencias relativas podrían ser más útiles para comprender la distribución relativa de las variables: Sepal.Length, Sepal.Width, Petal.Length y Petal.Width.

  • Generar una tabla de frecuencias absolutas con cada una de las variables del conjunto de datos Orange. ¿Todas las tablas generadas tienen sentido para vosotros?
data(Orange)
kable(table(Orange$Tree))
Var1 Freq
3 7
1 7
5 7
2 7
4 7
kable(table(Orange$age))
Var1 Freq
118 5
484 5
664 5
1004 5
1231 5
1372 5
1582 5
kable(table(Orange$circumference))
Var1 Freq
30 3
32 1
33 1
49 1
51 1
58 1
62 1
69 1
75 1
81 1
87 1
108 1
111 1
112 1
115 2
120 1
125 1
139 1
140 1
142 2
145 1
156 1
167 1
172 1
174 1
177 1
179 1
203 2
209 1
214 1
kable(prop.table(as.numeric(Orange$Tree)))
x
0.0190476
0.0190476
0.0190476
0.0190476
0.0190476
0.0190476
0.0190476
0.0380952
0.0380952
0.0380952
0.0380952
0.0380952
0.0380952
0.0380952
0.0095238
0.0095238
0.0095238
0.0095238
0.0095238
0.0095238
0.0095238
0.0476190
0.0476190
0.0476190
0.0476190
0.0476190
0.0476190
0.0476190
0.0285714
0.0285714
0.0285714
0.0285714
0.0285714
0.0285714
0.0285714
kable(prop.table(Orange$age))
x
0.0036561
0.0149961
0.0205732
0.0311077
0.0381410
0.0425097
0.0490163
0.0036561
0.0149961
0.0205732
0.0311077
0.0381410
0.0425097
0.0490163
0.0036561
0.0149961
0.0205732
0.0311077
0.0381410
0.0425097
0.0490163
0.0036561
0.0149961
0.0205732
0.0311077
0.0381410
0.0425097
0.0490163
0.0036561
0.0149961
0.0205732
0.0311077
0.0381410
0.0425097
0.0490163
kable(prop.table(Orange$circumference))
x
0.0073983
0.0143033
0.0214550
0.0283600
0.0295931
0.0350185
0.0357583
0.0081381
0.0170160
0.0273736
0.0384710
0.0424168
0.0500617
0.0500617
0.0073983
0.0125771
0.0184957
0.0266338
0.0283600
0.0342787
0.0345253
0.0078915
0.0152898
0.0276202
0.0411837
0.0441430
0.0515413
0.0527744
0.0073983
0.0120838
0.0199753
0.0308261
0.0350185
0.0429100
0.0436498
  • Generar una tabla de doble entrada entre las variables Tree y Age de Orange.
table(Orange$Tree, Orange$age)
##    
##     118 484 664 1004 1231 1372 1582
##   3   1   1   1    1    1    1    1
##   1   1   1   1    1    1    1    1
##   5   1   1   1    1    1    1    1
##   2   1   1   1    1    1    1    1
##   4   1   1   1    1    1    1    1

Ejercicio 2

Copiad y ejecutad el código siguiente de los dos vectores.

#código del enunciado
vect1 <- c(1,2,1,2,1,2,1,2,1,2,1,1,1,1,2,2,1,1,2,1)
vect2 <- c(1,1,2,2,2,1,2,1,1,2,1,2,1,1,1,2,1,1,1,1)

Responded a los apartados siguientes: a) Usando el vect1 creamos un nuevo vector llamado Bajo_peso que sea un factor con dos niveles. Las etiquetas corresponden a 1 = Bajo peso y 2 = Peso normal.

Bajo_peso <- factor(vect1, levels = c(1, 2), labels = c("Bajo peso", "Peso normal"))
Bajo_peso
##  [1] Bajo peso   Peso normal Bajo peso   Peso normal Bajo peso   Peso normal
##  [7] Bajo peso   Peso normal Bajo peso   Peso normal Bajo peso   Bajo peso  
## [13] Bajo peso   Bajo peso   Peso normal Peso normal Bajo peso   Bajo peso  
## [19] Peso normal Bajo peso  
## Levels: Bajo peso Peso normal
  1. Usando el vect2 creamos un nuevo vector llamado Fumador que sea un factor con dos niveles. Las etiquetas corresponden a 1 = Fuma y 2 = No fuma.
Fumador <- factor(vect2, levels = c(1, 2), labels = c("Fuma", "No fuma"))
Fumador
##  [1] Fuma    Fuma    No fuma No fuma No fuma Fuma    No fuma Fuma    Fuma   
## [10] No fuma Fuma    No fuma Fuma    Fuma    Fuma    No fuma Fuma    Fuma   
## [19] Fuma    Fuma   
## Levels: Fuma No fuma
  1. Creamos una tabla de contingencia con las dos variables anteriores con el nombre Tabla.
Tabla_Bpeso_Fumador <- table(Bajo_peso, Fumador)
Tabla_Bpeso_Fumador
##              Fumador
## Bajo_peso     Fuma No fuma
##   Bajo peso      8       4
##   Peso normal    5       3
  1. Miramos la relación de las variables anteriores con la prueba del ji cuadrado.
chi_sq_test_Bp_Fum <- chisq.test(Tabla_Bpeso_Fumador)
chi_sq_test_Bp_Fum
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  Tabla_Bpeso_Fumador
## X-squared = 0, df = 1, p-value = 1
  1. Miramos también cómo resulta el test de Fisher.
fisher_test_Bp_Fum <- fisher.test(Tabla_Bpeso_Fumador)
fisher_test_Bp_Fum
## 
##  Fisher's Exact Test for Count Data
## 
## data:  Tabla_Bpeso_Fumador
## p-value = 1
## alternative hypothesis: true odds ratio is not equal to 1
## 95 percent confidence interval:
##   0.1200513 10.9278345
## sample estimates:
## odds ratio 
##   1.189031

Ejercicio 3

  1. Activad el paquete de datos airquality del paquete datasets y generad los siguientes gráficos:
data("airquality")

Un gráfico de dispersión de la variable Ozone de color azul y con almohadillas (#) en vez de puntos.

plot(airquality$Ozone, 
     pch = "#",  
     col = "blue", 
     ylab = "Nivel de ozono",
     main = "Gráfico de dispersión de 'Ozone'")

Un gráfico de caja de color rojo con la variable Temp con el título Temperatura (en grados Farenheit).

boxplot(airquality$Temp,
        col = "red",  
        main = "Temperatura (en grados Fahrenheit)") 

  1. Activad el paquete de datos airmiles del paquete datasets y generad los siguientes gráficos:
data("airmiles")

Un gráfico de líneas de la serie de datos airmiles con el título Datos de pasajeros en vuelos comerciales (en miles) y de color azul (cadetblue2) y la etiqueta del eje x con Miles de pasajeros.

plot(airmiles,
     type = "l",  
     col = "cadetblue2",  
     main = "Datos de pasajeros en vuelos comerciales (en miles)",  
     xlab = "Miles de pasajeros")  

Un histograma de la serie de datos airmiles de color marrón (chocolate2).

hist(airmiles, 
     col = "chocolate2", 
     main = "Histograma de la serie de datos airmiles")  

  1. Representad los cuatro gráficos en una única imagen donde los veamos juntos.
par(mfrow = c(2, 2))

plot(airquality$Ozone, pch = "#", col = "blue", ylab = "Nivel de ozono",
     main = "Gráfico de dispersión de 'Ozone'")
boxplot(airquality$Temp,col = "red",main = "Temperatura (en grados Fahrenheit)")

plot(airmiles,type = "l", col = "cadetblue2",main = "Datos de pasajeros en vuelos comerciales (en miles)",  
     xlab = "Miles de pasajeros")

hist(airmiles, col = "chocolate2", main = "Histograma de la serie de datos airmiles")  

Ejercicio 4

Intentad reproducir el ejemplo 7 de este LAB con unos datos simulados por vosotros. No hace falta que sean parecidos, pero es necesario que podáis hacer diferentes gráficos estadísticos con el comando plot().

set.seed(123)
Feature1 <- rnorm(800) #simulamos una variable x1
Target1 <- Feature1 + rnorm(800) #simulamos una variable y1
plot(Feature1, Target1,  pch = 19, col=rgb(0.7, 0.2, 0, 0.4),main="Gráfico de dispersión") #
abline(lm(Target1~Feature1),lwd=2,col=rgb(0.1,0,1,0.5)) #creamos la recta de regresión

plot(density(Feature1), main="Densidad de Feature1", col="blue") #gráfico de densidad para ver cómo es la distribución
lines(density(Target1), col="darkred") #generamos un gráfico con las densidades de las dos variables.

Ejercicio 5

Para poder practicar la creación de gráficos con ggplot2, vamos a crear seis gráficos con diferentes características y con diferentes conjuntos de datos de paquetes trabajados anteriormente.

  1. Con los datos airquality del paquete datasets cread un gráfico de dispersión simple, pero con la recta de regresión ajustada en color rojo (darkred).
data(airquality)

ggplot(airquality, aes(Solar.R, Temp)) +
  geom_point() +
  geom_smooth(method="lm", col="darkred", se=FALSE)

  1. Con los datos airquality del paquete datasets cread un gráfico de dispersión con las variables Solar.R y Temp con sus respectivas etiquetas de eje. Los colores y la forma de los puntos deben ser en función de la variable Month convertida a factor.
ggplot(airquality, aes(Solar.R, Temp, color = factor(Month), shape=factor(Month))) +
  geom_point() +
  labs(x="Radiación solar", y= "Temperatura")

  1. Con los datos de Birthwt del paquete MASS mostrad la distribución de la variable age que tenga el borde de color negro y azul en el interior de las barras.

  2. Con los datos de Birthwt del paquete MASS mostrad la distribución de la variable age, pero separada en dos gráficos (fumador/no fumador) por la variable smoke.

Ejercicio 6

Cread un gráfico con unos datos extraídos del paquete Datasets de R y guardadlo como imagen (.jpg) con el nombre migrafic1 y, también, como documento en PDF con el nombre migrafic2. Haced una captura de pantalla del fichero generado.

df_Indometh <- Indometh

#jpeg("Datos/migrafic1.jpg") 
#boxplot(df_Indometh$time, col="green")
#dev.off 

#pdf("Datos/migrafic2.pdf")
#boxplot(df_Indometh$time, col="green")
#dev.off 

Ejercicio 7

Para practicar la regresión lineal simple usaremos el conjunto de datos Orange que se encuentra en la librería tidyverse y que tiene información sobre tres variables (árbol, edad en días desde que se sembró el árbol y circunferencia del tronco en centímetros) de 35 naranjos. Queremos saber qué valor de circunferencia tendrá un árbol seiscientos días después de plantarlo. Cread para ello un modelo lineal y practicad la regresión lineal paso a paso con los pasos que habéis visto en este laboratorio.

df_orange <- Orange

pairs(df_orange)

Calculamos el grado de relación lineal de las variables circumference y age.

kable(cor(df_orange$circumference, df_orange$age))
x
0.9135189

Creamos un modelo de regresión lineal en el que la variable objetivo es el valor de la circumferencia y obtenido a partir de la edad del árbol (en días).

LM_cir_edad <- lm(circumference ~ age, data = df_orange)
summary(LM_cir_edad)
## 
## Call:
## lm(formula = circumference ~ age, data = df_orange)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -46.310 -14.946  -0.076  19.697  45.111 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 17.399650   8.622660   2.018   0.0518 .  
## age          0.106770   0.008277  12.900 1.93e-14 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 23.74 on 33 degrees of freedom
## Multiple R-squared:  0.8345, Adjusted R-squared:  0.8295 
## F-statistic: 166.4 on 1 and 33 DF,  p-value: 1.931e-14

La ecuación de la recta de mínimos cuadrados obtenida es:

\(y= 0.10677x+17.3997\)

plot(df_orange$age, df_orange$circumference, xlab='Edad (días)', ylab='Circumferencia (cm)', 
     main = "Circumferencia de un naranjo en función de la edad ")
abline(LM_cir_edad, col = "blue")

Validación del modelo

residuos <- rstandard(LM_cir_edad)
valores.ajustados <- fitted(LM_cir_edad)
plot(valores.ajustados, residuos, main = "Residuos respecto valores ajustados")
abline(h=0, col="red")

Comprobación de la hipotesis de normalidad

qqnorm(residuos)
qqline(residuos)

Comprobamos el valor de la circunferencia de un árbol seiscientos días después de plantarlo.

pred_circ <- data.frame(age = 600)
predict(LM_cir_edad, pred_circ)
##        1 
## 81.46185

Intervalo de confianza (al 95 %) de los parámetros estimados

confint(LM_cir_edad)
##                   2.5 %     97.5 %
## (Intercept) -0.14328303 34.9425835
## age          0.08993141  0.1236092

Ejercicio 8

Repetid los gráficos (aquellos que podáis) de la regresión lineal simple del ejercicio anterior pero ahora con ggplot2. Nota: en caso de haber elaborado el ejercicio 7 con gráficos de este tipo, creadlos con gráficos base.

Grafico de dispersión y recta de regresión

ggplot(LM_cir_edad) +
  geom_point(aes(x = age, y = circumference)) +
  geom_line(aes(x = age, y = .fitted), col="blue")+
  labs(x="Edad (días)", y="circumferencia (cm) ",
       title = "Regresión lineal - Circumferencia de un naranjo en función de la edad ")

Residuos

ggplot(LM_cir_edad, aes(x = .fitted, y = .resid)) +
  geom_point() +
  geom_hline(yintercept = 0, col="red") +
  labs(title='Residuos - Regresión lineal - Circumferencia = f(edad)',
       x='Valores ajustados', y='Residuos')

Comprobación de la hipótesis de normalidad

ggplot(data.frame(residuos), aes(sample=residuos)) + 
  geom_qq() + 
  geom_qq_line(colour = "red") +  # Línea de referencia en rojo
  ggtitle("Gráfico Q-Q de los residuos") +
  xlab("Cuantiles teóricos") +
  ylab("Cuantiles de los residuos")

Ejercicio 9

Activad el conjunto de datos PlantGrowth del paquete datasets de R. Este archivo tiene los resultados de un experimento para comparar los rendimientos medios por el peso seco de las plantas (weight) obtenidos bajo un control y dos condiciones de tratamiento diferentes (group factor).

df_planta <- PlantGrowth
  • ¿Creéis que hay diferencias entre tratamientos?

En el siguiente gráfico se observa la diferencia en la distribución del peso según el tipo de tratamiento.

ggplot(df_planta, aes(x = group, y = weight, fill=group)) +
  geom_boxplot() +
   labs(x = "Grupo de tratamiento", y = "Peso",
        title ="Distribución del peso por grupo de tratamiento")

  • Se cumplen las condiciones para poder aplicar una ANOVA. ¿Qué pruebas os planteáis?
modelo_anova <- aov(weight ~ group, data = df_planta)
summary(modelo_anova)
##             Df Sum Sq Mean Sq F value Pr(>F)  
## group        2  3.766  1.8832   4.846 0.0159 *
## Residuals   27 10.492  0.3886                 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Vemos un resultado estadísticamente significativo, ya que sí que hay diferencias entre grupos (p-value < 0.05).

Ejercicio 10

Buscad información del paquete Plotly para la creación de gráficos interactivos y generad un histograma o un gráfico de barras interactivo. Explicad qué se puede hacer con este gráfico.

Respuesta

Imaginemos que queremos hacer una comparación de los ingreso hospitalarios mensuales medios de tres hospitales durante un periodo de 2 años.

## Generamos una variable temporal
set.seed(47)
Fecha <- seq(as.Date("2022/1/1"), by = "month", length.out = 24)
distribution1 <- round(rnorm(30, 250, 100))
distribution2 <- round(rnorm(30, 225, 110))
distribution3 <- round(rnorm(30, 230, 130))
Hospital_1 <- sample(distribution1, 24, replace=TRUE)
Hospital_2 <- sample(distribution2, 24, replace=TRUE)
Hospital_3 <- sample(distribution3, 24, replace=TRUE)

df_Hospital <- data.frame(Fecha,Hospital_1,Hospital_2,Hospital_3)

En el siguiente gráfico:

  • se puede seleccionar de que hospitales queremos ver los datos y se reescalan automáticamente las barras depediendo de si seleccionamos uno, dos o los tres hospitales, mediante la selección del hospital etiquetado en la leyenda.(Arriba a la derecha)

  • se puede seleccionar el periodo temporal en la barra deslizable en la parte inferior.

  • arriba a la izquierda hay la opción de seleccionar los últimos 6, 12, 18 meses o todo el periodo.

plot_hospital <- plot_ly(df_Hospital, x = ~ Fecha,width = 700,height = 600)
plot_hospital <- plot_hospital %>% add_trace(y= ~ Hospital_1, type = "bar", name = "Hospital 1",
                                             text = Hospital_1, textposition = 'auto', 
                                             marker = list(color = '#1270aa',
                                                           line = list(color = '#294077', width = 1.5)))
plot_hospital <- plot_hospital %>% add_trace(y= ~ Hospital_2, type = "bar", name = "Hospital 2",
                                             text = Hospital_2, textposition = 'auto', 
                                             marker = list(color = '#f09ba0',
                                                           line = list(color = '#294077', width = 1.5)))

plot_hospital <- plot_hospital %>% add_trace(y= ~ Hospital_3, type = "bar", name = "Hospital 3",
                                             text = Hospital_3, textposition = 'auto', 
                                             marker = list(color = '#500ba0',
                                                           line = list(color = '#294077', width = 1.5)))
plot_hospital <- plot_hospital %>% layout(
    title = "Ingresos medios mensuales en Hospitales",
    xaxis = list(
      rangeselector = list(
        buttons = list(
          list(
            count = 6,
            label = "6 m",
            step = "month",
            stepmode = "backward"),
          list(
            count = 1,
            label = "1 año",
            step = "year",
            stepmode = "backward"),
          list(
            count = 18,
            label = "1.5 años",
            step = "month",
            stepmode = "backward"),          
          list(label = "todo",step = "all"))),
      rangeslider = list(type = "date")),
    yaxis = list(title = "Ingresos"))

plot_hospital

Caso práctico

A partir de unos datos bioclínicos o biosanitarios que escojáis y que importéis a R, explicad sus variables (mínimo de ocho variables) y también:

  • Realizad un resumen estadístico completo del dataset y explicad los resultados.

  • Realizad cinco gráficos básicos con las variables, explicad su significado y guardadlos como imágenes (jpeg o bmp).

  • Realizad dos gráficos con el comando ggplot(), explicad su significado y guardadlos como imágenes (jpeg o bmp).

  • Generad una regresión lineal entre dos de sus variables paso a paso y comentad los resultados obtenidos.

Elección de datos

Datos extraidos de: (https://archive.ics.uci.edu/dataset/15/breast+cancer+wisconsin+original)

Información de las variables

Variable Rango de valores
1. Sample code number: id number
2. Clump Thickness: 1 - 10
3. Uniformity of Cell Size: 1 - 10
4. Uniformity of Cell Shape: 1 - 10
5. Marginal Adhesion: 1 - 10
6. Single Epithelial Cell Size: 1 - 10
7. Bare Nuclei: 1 - 10
8. Bland Chromatin: 1 - 10
9. Normal Nucleoli: 1 - 10
10. Mitoses: 1 - 10
11. Class: (2 for benign, 4 for malignant)
df_breastcancer_wo <- read.table("Datos/breast-cancer-wisconsin.data", sep=",",dec=".")

#Se renombran las variables según la descripción del dataset
colnames(df_breastcancer_wo) <- c("Sample_code_number","Clump_thickness","Uniformity_of_cell_size","Uniformity_of_cell_shape","Marginal_adhesion", "Single_epithelial_cell_size","Bare_nuclei","Bland_chromatin","Normal_nucleoli","Mitoses","Class")

Resumen estadístico

summary(df_breastcancer_wo)
##  Sample_code_number Clump_thickness  Uniformity_of_cell_size
##  Min.   :   61634   Min.   : 1.000   Min.   : 1.000         
##  1st Qu.:  870688   1st Qu.: 2.000   1st Qu.: 1.000         
##  Median : 1171710   Median : 4.000   Median : 1.000         
##  Mean   : 1071704   Mean   : 4.418   Mean   : 3.134         
##  3rd Qu.: 1238298   3rd Qu.: 6.000   3rd Qu.: 5.000         
##  Max.   :13454352   Max.   :10.000   Max.   :10.000         
##  Uniformity_of_cell_shape Marginal_adhesion Single_epithelial_cell_size
##  Min.   : 1.000           Min.   : 1.000    Min.   : 1.000             
##  1st Qu.: 1.000           1st Qu.: 1.000    1st Qu.: 2.000             
##  Median : 1.000           Median : 1.000    Median : 2.000             
##  Mean   : 3.207           Mean   : 2.807    Mean   : 3.216             
##  3rd Qu.: 5.000           3rd Qu.: 4.000    3rd Qu.: 4.000             
##  Max.   :10.000           Max.   :10.000    Max.   :10.000             
##  Bare_nuclei        Bland_chromatin  Normal_nucleoli     Mitoses      
##  Length:699         Min.   : 1.000   Min.   : 1.000   Min.   : 1.000  
##  Class :character   1st Qu.: 2.000   1st Qu.: 1.000   1st Qu.: 1.000  
##  Mode  :character   Median : 3.000   Median : 1.000   Median : 1.000  
##                     Mean   : 3.438   Mean   : 2.867   Mean   : 1.589  
##                     3rd Qu.: 5.000   3rd Qu.: 4.000   3rd Qu.: 1.000  
##                     Max.   :10.000   Max.   :10.000   Max.   :10.000  
##      Class     
##  Min.   :2.00  
##  1st Qu.:2.00  
##  Median :2.00  
##  Mean   :2.69  
##  3rd Qu.:4.00  
##  Max.   :4.00

La variable Bare_nuclei se identifica como chr por tener Missing Values pero la transformamos en numérica y volvemos a imprimir las características pero solo de esta variable.

df_breastcancer_wo$Bare_nuclei <- as.numeric(df_breastcancer_wo$Bare_nuclei)
summary(df_breastcancer_wo$Bare_nuclei)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   1.000   1.000   3.545   6.000  10.000      16
  • Sample_code_number: Es el identificador único para cada muestra del dataset.

  • Para las variables numéricas Clump_thickness, Uniformity_of_cell_size, Uniformity_of_cell_shape, Marginal_adhesion, Single_epithelial_cell_size, Bare_nuclei, Bland_chromatin, Normal_nucleoli, Mitoses: Estas son características cuantitativas relacionadas con las células observadas en las muestras. Para cada variable se incluyen resultados del valor mínimo, el valor máximo, la mediana, la media y de los primer y tercer cuartil. Con esta información se puede comprobar la distribución de cadauna de estas variables.

  • Class: Variable categórica que indica si en el caso (observación) se ha clasificado el tumor como benigno (2) o maligno (4) por lo que creamos una variable adicional de Tumor.

df_breastcancer_wo$tumor <- factor(df_breastcancer_wo$Class,levels = c(2,4), labels = c("Benigno","Maligno")) 

Cinco gráficos básicos

1. Primero hacemos un gráfico de correlación por pares:

No tenemos en cuenta la variable Bare_nuclei que tiene NA.

pairs(df_breastcancer_wo[,c(2,3,4,5,6,8,9,10,11)])

2. Frecuencia de las clases de tumor benigno y maligno:

Hacemos un diagrama de barras para visualizar la frecuencia.

barplot(table(df_breastcancer_wo$Class),
        main = "Casos de diagnosis de tumores malignos y benignos",
        xlab = "Clase",
        ylab = "Frecuencia",
        ylim = c(0,500),
        names.arg = c("Benigno", "Maligno")) 

3. Histograma - Distribución según el grosor del tumor

hist(df_breastcancer_wo$Clump_thickness, xlab = 'Grosor del tumor(Clump thickness)', 
     ylab = 'Numero de casos', main = 'Distribución según el grosor del tumor', 
     xlim=c(0,10), ylim=c(0,250), col = 'orange', border = "black")

4. Boxplot - Distribución según el grosor del tumor

boxplot(df_breastcancer_wo$Single_epithelial_cell_size, ylab = 'Tamaño', main = 'Tamaño de la célula epitelial única', 
        col = 'yellow', border = "black")

5. Plot de densidad

plot(density(df_breastcancer_wo$Bland_chromatin), xlab = 'Cromatina blanda (Bland chromatin)', 
     ylab = 'Frecuencia relativa', main = 'Distribución de la Cromatina blanda', col = 'blue', lwd = 3)

Dos gráficos con el comando ggplot(), explicad su significado y guardadlos como imágenes (jpeg o bmp).

En el siguiente gráfico se muestra la distribución del tamaño de la célula en diagramas de caja dependiendo de si el tumor es maligno o benigno.

ggp_size_tumor <- ggplot(df_breastcancer_wo, aes(x = tumor, y = Uniformity_of_cell_size, fill=tumor)) +
  geom_boxplot() +
  labs(x = "Clasificación del tumor", y = "Uniformidad del tamaño de la célula",
       title = "Distribución Uniformidad del tamaño de la célula según el tumor") 

ggp_size_tumor

#ggsave("Datos/ggp_size_tumor.jpg")

En el siguiente gráfico de dispersión se muestra la relación entre las variables numéricas Mitoses y Marginal_adhesion, además se agrega una tercera variable categórica para ver como influye la relación de estas variables según las categorías de esta tercera variable. Se añade más dispersión porque se trata de enteros y se superponen los puntos.

ggp_mit_MA_tumor <- ggplot(df_breastcancer_wo, aes(x=Mitoses, y=Marginal_adhesion, col=tumor)) + 
  geom_point(position = position_jitter(width = 0.2, height = 0.2)) +
  labs(title= "Relación entre Mitosis y la Adhesión Marginal según el tipo de tumor", 
       x = "Mitosis", 
       y = "Adhesión Marginal", 
       color = "Tipo de Tumor")

ggp_mit_MA_tumor

#ggsave("Datos/ggp_mit_MA_tumor.jpg")

Generad una regresión lineal entre dos de sus variables paso a paso y comentad los resultados obtenidos.

Generación del LM

Se genera un modelos de regresión lineal con la variable respuesta Class (tipo de tumor como variable numérica) y el predictor Uniformity_of_cell_size.

LM_class <- lm(Uniformity_of_cell_shape ~ Uniformity_of_cell_size ,data=df_breastcancer_wo)
summary(LM_class)
## 
## Call:
## lm(formula = Uniformity_of_cell_shape ~ Uniformity_of_cell_size, 
##     data = df_breastcancer_wo)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -7.2714 -0.3222 -0.3222  0.6778  6.0281 
## 
## Coefficients:
##                         Estimate Std. Error t value Pr(>|t|)    
## (Intercept)              0.43894    0.06798   6.457    2e-10 ***
## Uniformity_of_cell_size  0.88324    0.01555  56.818   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 1.253 on 697 degrees of freedom
## Multiple R-squared:  0.8224, Adjusted R-squared:  0.8222 
## F-statistic:  3228 on 1 and 697 DF,  p-value: < 2.2e-16

En este resultado podemos observar los parámetros de la ecuación de la recta de mínimos cuadrados. Estos vienen dados por la columna «Estimate» del apartado «Coefficients» y relacionan la uniformidad de la forma de la célula en función de la uniformidad del tamaño de la célula.

La ecuación de la recta de mínimos cuadrados es: \(y=0.43894+0.88324*x\)

Vemos en esta tabla que el coeficiente de determinación (mide el ajuste de la recta a los datos) es de 0.8224 en Multiple R-squared.

La desviación típica de los errores es 1.253 (Residual standard error).

Los errores típicos de los estimadores de los parámetros β0 y β1 se encuentran en la columna «Std. Error». Sus valores son 0.06798 y 0.01555, respectivamente.

El p-valor es < 2.2e-16, por lo tanto < 0.05, lo que indica que el predictor es estadísticamente significativo.

Se genera el gráfico de dispersión con la recta de mínimos cuadrados ajustada.

plot(df_breastcancer_wo$Uniformity_of_cell_size, df_breastcancer_wo$Uniformity_of_cell_shape, xlab='Uniformidad del tamaño de la célula', ylab='Uniformidad del forma de la célula')
abline(LM_class,col="blue")

Se valida el modelo para ver que se cumplen las condiciones representando los residuos estandarizados frente a los valores ajustados

res_class <- rstandard(LM_class)
fit_class <- fitted(LM_class)
plot(fit_class, res_class)

Se comprueba la hipótesis de normalidad mediante un Q-Q plot de los residuos.

qqnorm(res_class)
qqline(res_class)

Si queremos saber el intervalo de confianza (al 95 %) de los parámetros estimados.

confint(LM_class)
##                             2.5 %    97.5 %
## (Intercept)             0.3054732 0.5724062
## Uniformity_of_cell_size 0.8527204 0.9137617