1 Librerías

library(moments)
library(corrplot)
library(lattice)
library(knitr)

2 Tratamiento de datos

data <- read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/heart-disease/processed.cleveland.data",
                 header=FALSE,sep=",",na.strings = '?')

#RENOMBRAR LAS COLUMNAS
names(data) <- c( "age", "sex", "cp", "trestbps", "chol","fbs", "restecg","thalach","exang", "oldpeak","slope", "ca", "thal", "num")
 
data$sex <- factor(data$sex,levels = c(0,1),labels = c("Female","Male"))
data$cp <- factor(data$cp,levels = c(1,2,3,4),
                  labels = c("Typical angina","Atypical angina","Non-anginal pain","Asymptomatic"))
data$fbs <- as.logical(data$fbs)
data$restecg <- factor(data$restecg,levels = c(0,1,2),labels = c("Normal","Having ST-T wave abnormality","Showing probable or definite left ventricular hypertrophy by Estes' criteria"))
data$exang <- factor(data$exang,levels = c(0,1),labels = c("No","Yes"))
data$slope <- factor(data$slope,levels = c(1,2,3),labels = c("Upsloping","Flat","Downsloping"))
data$thal <- factor(data$thal,levels = c(3,6,7),labels = c("Normal","Fixed defect","Reversable defect"))

3 Estadística descriptiva univariante

3.1 Variables cuantitativas

cortes <- function(vector){
  k <- nclass.Sturges(vector)
  ancho <- (max(vector)-min(vector))/k
  corte <- seq(min(vector)-1,min(vector)+(k*ceiling(ancho)),ceiling(ancho))
  return(corte)
}

3.1.1 Age

En la siguiente gráfica se presenta el Histograma de las Edades de los pacientes y se puede ver que la distribución de esta variable tiene un ligero sesgo negativo, es decir que hay pocos datos a la izquierda de la misma. Por otro lado, la mayoría de los pacientes tienen entre 50 y 65 años.

hist.age <- hist(data$age,main="Histograma de las Edades de los pacientes",xlab = "Edades",
     ylab = "Frecuencias",col = 2,breaks = cortes(data$age))

El diagrama de caja muestra que la distribución de las edades de los pacientes, que están más concentrada en el tercer 25% de la muestra , es decir entre 48 y 61 años, mientras que, en general, el 50% de los pacientes tienen edades menores a 56 años. También es importante destacar que no existen edades atípicas.

boxplot(data$age,main="Diagrama de Caja de las Edades de los pacientes",xlab = "Edades",
        horizontal = T,col = 2)

Los siguientes datos muestran un resumen de las estadísticas descriptivas más relevantes de las edades de los pacientes. En promedio, los pacientes tienen 54.43 años, valores que se encuentran dispersos a 9.04 años alrededor de la media. La mitad de los pacientes tienen menos de 56 años y existe un sesgo negativo, es decir que hay un mayor número de pacientes con edades por encima de la media.

mean(data$age)
## [1] 54.43894
median(data$age)
## [1] 56
sd(data$age)
## [1] 9.038662
quantile(data$age)
##   0%  25%  50%  75% 100% 
##   29   48   56   61   77
kurtosis(data$age)
## [1] 2.465477
skewness(data$age)
## [1] -0.2080241

A continuación, se muestra la tabla de frecuencias de las edades de los pacientes. En la misma se puede ver que la mayoría de ellos tienen edades entre 53 y 58 años, siendo estos 71 pacientes o más del 23% del total. Por otro lado, un paciente es menor de 33 años y 3 son mayores a 73,siendo estos últimos valores menos del 0.1% del total.

fa.age <- table(cut(data$age,breaks = hist.age$breaks,include.lowest = T))
Ma.age <- hist.age$mids
Fa.age <- cumsum(fa.age)
fr.age <- prop.table(fa.age)
Fr.age <- cumsum(fr.age)
tabla.age <- cbind(fa=fa.age,Ma=Ma.age,Fa=Fa.age,fr=fr.age,Fr=Fr.age)
kable(tabla.age,align = "c")
fa Ma Fa fr Fr
[28,33] 1 30.5 1 0.0033003 0.0033003
(33,38] 10 35.5 11 0.0330033 0.0363036
(38,43] 33 40.5 44 0.1089109 0.1452145
(43,48] 38 45.5 82 0.1254125 0.2706271
(48,53] 45 50.5 127 0.1485149 0.4191419
(53,58] 71 55.5 198 0.2343234 0.6534653
(58,63] 54 60.5 252 0.1782178 0.8316832
(63,68] 38 65.5 290 0.1254125 0.9570957
(68,73] 10 70.5 300 0.0330033 0.9900990
(73,78] 3 75.5 303 0.0099010 1.0000000

3.1.2 trestbps

En la siguiente gráfica se presenta el Histograma de las Presión Arterial de los pacientes y se puede ver que la distribución de esta variable tiene un ligero sesgo positivo, es decir que hay pocos datos a la derecha de la misma. Por otro lado, la mayoría de los pacientes tienen una presión entre 115 y 140.

hist.tres <- hist(data$trestbps,main="Histograma de la Presión Arterial de los pacientes",xlab = "Presión Arterial",
                 ylab = "Frecuencias",col = 3,breaks = cortes(data$trestbps))

El diagrama de caja muestra que la distribución de la Presión Arterial de los pacientes está más concentrada en el segundo 25% de las mismas, es decir entre 120 y 130, mientras que, en general, el 50% de los pacientes tienen una presión menor a 130. También es importante destacar que existen niveles de presión atípicos muy altos.

boxplot(data$trestbps,main="Diagrama de Caja de la Presión Arterial de los pacientes",xlab = "Presión Arterial",
        horizontal = T,col = 3)

Los siguientes datos muestran un resumen de las estadísticas descriptivas más relevantes de la Presión Arterial de los pacientes. En promedio, los pacientes tienen una presión de 131.69, estando estos valores, dispersos en 17.60 alrededor de la media. La mitad de los pacientes tienen una presión menor a 130 y existe un sesgo positivo, es decir que hay un mayor número de pacientes con niveles de presión arterial por debajo de la media.

mean(data$trestbps)
## [1] 131.6898
median(data$trestbps)
## [1] 130
sd(data$trestbps)
## [1] 17.59975
quantile(data$trestbps)
##   0%  25%  50%  75% 100% 
##   94  120  130  140  200
kurtosis(data$trestbps)
## [1] 3.845881
skewness(data$trestbps)
## [1] 0.7025346

A continuación, se muestra la tabla de frecuencias de la Presión Arterial de los pacientes. En la misma se puede ver que la mayoría de ellos tienen una presión entre 126 y 137, siendo estos 71 pacientes o más del 23% del total. Por otro lado, tan solo dos pacientes registran una presión mayor a 181, representando menos del 0.1% del total.

fa.tres <- table(cut(data$trestbps,breaks = hist.tres$breaks,include.lowest = T))
Ma.tres <- hist.tres$mids
Fa.tres <- cumsum(fa.tres)
fr.tres <- prop.table(fa.tres)
Fr.tres <- cumsum(fr.tres)
tabla.tres <- cbind(fa=fa.tres,Ma=Ma.tres,Fa=Fa.tres,fr=fr.tres,Fr=Fr.tres)
kable(tabla.tres,align = "c")
fa Ma Fa fr Fr
[93,104] 10 98.5 10 0.0330033 0.0330033
(104,115] 42 109.5 52 0.1386139 0.1716172
(115,126] 70 120.5 122 0.2310231 0.4026403
(126,137] 71 131.5 193 0.2343234 0.6369637
(137,148] 58 142.5 251 0.1914191 0.8283828
(148,159] 26 153.5 277 0.0858086 0.9141914
(159,170] 17 164.5 294 0.0561056 0.9702970
(170,181] 7 175.5 301 0.0231023 0.9933993
(181,192] 1 186.5 302 0.0033003 0.9966997
(192,203] 1 197.5 303 0.0033003 1.0000000

3.1.3 chol

En la siguiente gráfica se presenta el Histograma del Nivel de Colesterol de los pacientes y se puede ver que la distribución de esta variable tiene un sesgo positivo, es decir que hay pocos datos a la derecha de la misma, así como también algunos datos atípicos. Por otro lado, la mayoría de los pacientes tienen un nivel de colesterol entre 200 y 300.

hist.chol <- hist(data$chol,main="Histograma del Nivel de Colesterol de los pacientes",xlab = "Nivel de Colesterol",
                  ylab = "Frecuencias",col = 4,breaks = cortes(data$chol))

El diagrama de caja muestra que la distribución del Nivel de Colesterol de los pacientes está más concentrada en el segundo 25% de los mismos, es decir entre 211 y 241, mientras que, en general, el 50% de los pacientes tienen un nivel de colesterol menor a 241. También es importante destacar que existen niveles de colesterol muy altos, que no siguen el mismo comportamiento que los demás.

boxplot(data$chol,main="Diagrama de Caja del Nivel de Colesterol de los pacientes",xlab = "Nivel de Colesterol",
        horizontal = T,col = 4)

Los siguientes datos muestran un resumen de las estadísticas descriptivas más relevantes del Nivel de Colesterol de los pacientes. En promedio, los pacientes tienen un nivel de colesterol de 246.69, valores que están dispersos en 51.78 alrededor de la media. La mitad de los pacientes tienen un nivel de colesterol menor a 241 y existe un sesgo positivo, es decir que hay un mayor número de pacientes con niveles de colesterol por debajo de la media.

mean(data$chol)
## [1] 246.6931
median(data$chol)
## [1] 241
sd(data$chol)
## [1] 51.77692
quantile(data$chol)
##   0%  25%  50%  75% 100% 
##  126  211  241  275  564
kurtosis(data$chol)
## [1] 7.398208
skewness(data$chol)
## [1] 1.129874

A continuación, se muestra la tabla de frecuencias del Nivel de Colesterol de los pacientes. En la misma se puede ver que la mayoría de ellos, tienen un nivel de colesterol entre 213 y 257, siendo 106 pacientes, casi el 35% del total. Por otro lado, tan solo un paciente registra un nivel de colesterol mayor a 433,un dato atípico, que resulta menos del 0.1% del total.

fa.chol <- table(cut(data$chol,breaks = hist.chol$breaks,include.lowest = T))
Ma.chol <- hist.chol$mids
Fa.chol <- cumsum(fa.chol)
fr.chol <- prop.table(fa.chol)
Fr.chol <- cumsum(fr.chol)
tabla.chol <- cbind(fa=fa.chol,Ma=Ma.chol,Fa=Fa.chol,fr=fr.chol,Fr=Fr.chol)
kable(tabla.chol,align = "c")
fa Ma Fa fr Fr
[125,169] 12 147 12 0.0396040 0.0396040
(169,213] 72 191 84 0.2376238 0.2772277
(213,257] 106 235 190 0.3498350 0.6270627
(257,301] 69 279 259 0.2277228 0.8547855
(301,345] 36 323 295 0.1188119 0.9735974
(345,389] 3 367 298 0.0099010 0.9834983
(389,433] 4 411 302 0.0132013 0.9966997
(433,477] 0 455 302 0.0000000 0.9966997
(477,521] 0 499 302 0.0000000 0.9966997
(521,565] 1 543 303 0.0033003 1.0000000

3.1.4 thalach

En la siguiente gráfica se presenta el Histograma del Máximo Ritmo Cardíaco de los pacientes y se puede ver que la distribución de esta variable tiene un ligero sesgo negativo, es decir que hay pocos datos a la izquierda de la misma. Por otro lado, la mayoría de los pacientes tienen un ritmo cardíaco máximo entre 140 a 170.

hist.tha <- hist(data$thalach,main="Histograma del Máximo Ritmo Cardíaco de los pacientes",xlab = "Ritmo Cardíaco",
                  ylab = "Frecuencias",col = 5,breaks = cortes(data$thalach))

El diagrama de caja muestra que la distribución del Ritmo Cardíaco Máximo en los pacientes está más concentrada en el tercer 25% de los mismos, es decir entre 133.5 y 166 latidos por minuto, mientras que en general, el 50% de los pacientes tienen un ritmo cardiaco máximo menor a 153 latidos por minuto. También es importante destacar que existe un registro de ritmo cardiaco muy bajo, considerado como un dato atípico.

boxplot(data$thalach,main="Diagrama de Caja del Máximo Ritmo Cardíaco de los pacientes",xlab = "Ritmo Cardíaco",
        horizontal = T,col = 5)

Los siguientes datos muestran un resumen de las estadísticas descriptivas más relevantes del Máximo Ritmo Cardíaco de los pacientes. En promedio, los pacientes tienen un ritmo cardíaco máximo de 149.61 lpm, valores dispersos en 22.88 latidos alrededor de la media. La mitad de los pacientes tienen un ritmo cardíaco menor a 153 latidos por minuto y existe un sesgo negativo, es decir que hay un mayor número de pacientes con una frecuencia cardíaca por encima de la media.

mean(data$thalach)
## [1] 149.6073
median(data$thalach)
## [1] 153
sd(data$thalach)
## [1] 22.875
quantile(data$thalach)
##    0%   25%   50%   75%  100% 
##  71.0 133.5 153.0 166.0 202.0
kurtosis(data$thalach)
## [1] 2.927602
skewness(data$thalach)
## [1] -0.5347844

A continuación, se muestra la tabla de frecuencias del Máximo Ritmo Cardíaco de los pacientes. En la misma se puede ver que la mayoría de ellos tienen un ritmo cardíaco entre 154 y 168 lpm, siendo éstos 76 pacientes o poco más del 25% del total. Por otro lado, tan solo un paciente registra un ritmo cardiaco menor a 84 y otro mayor a 196 lpm respectivamente, representando menos del 0.1% del total.

fa.tha <- table(cut(data$thalach,breaks = hist.tha$breaks,include.lowest = T))
Ma.tha <- hist.tha$mids
Fa.tha <- cumsum(fa.tha)
fr.tha <- prop.table(fa.tha)
Fr.tha <- cumsum(fr.tha)
tabla.tha <- cbind(fa=fa.tha,Ma=Ma.tha,Fa=Fa.tha,fr=fr.tha,Fr=Fr.tha)
kable(tabla.tha,align = "c")
fa Ma Fa fr Fr
[70,84] 1 77 1 0.0033003 0.0033003
(84,98] 6 91 7 0.0198020 0.0231023
(98,112] 16 105 23 0.0528053 0.0759076
(112,126] 33 119 56 0.1089109 0.1848185
(126,140] 35 133 91 0.1155116 0.3003300
(140,154] 68 147 159 0.2244224 0.5247525
(154,168] 76 161 235 0.2508251 0.7755776
(168,182] 57 175 292 0.1881188 0.9636964
(182,196] 10 189 302 0.0330033 0.9966997
(196,210] 1 203 303 0.0033003 1.0000000

3.2 Variables cualitativas

3.2.1 Sex

A continuación, se presenta un diagrama de barras correspondiente al Sexo de los pacientes. En el mismo se puede ver que la mayoría de los pacientes son hombres y representan a casi el 68% del total, mientras que las mujeres, poco más del 32%. De manera similar, se presentan los mismos resultados con el diagrama circular.

barplot(table(data$sex),main = "Diagrama de barras por Sexo",xlab = "Sexo",ylab = "Frecuencias",col = 6)

pie(table(data$sex),main = "Diagrama circular por Sexo",xlab = "Sexo",col = c("pink","lightblue"))

3.2.2 cp

A continuación, se presenta un diagrama de barras correspondiente al Tipo de Dolor en el Pecho de los pacientes. En el mismo se puede ver que la mayoría de los pacientes no presentan dolor en el pecho y representan a más el 47% del total, mientras que los pacientes con angina típico son menos del 8%. De manera similar, se presentan los mismos resultados con el diagrama circular.

barplot(table(data$cp),main = "Diagrama de barras por Tipo de Dolor en el Pecho",xlab = "Tipo de Dolor en el pecho",ylab = "Frecuencias",col = 7)

pie(table(data$cp),main = "Diagrama circular por Tipo de Dolor en el Pecho",xlab = "Tipo de Dolor",col = seq(2,5))

3.2.3 exang

A continuación, se presenta un diagrama de barras correspondiente a los pacientes que presentaron Angina inducida por Ejercicio. En el mismo se puede ver que la mayoría de los pacientes no presentaron angina y representan a más del 67% del total, mientras que aquellos que sí fueron inducidos de angina durante el ejercicio, poco más del 32%. De la misma manera, se presentan los mismos resultados con el diagrama circular.

barplot(table(data$exang),main = "Diagrama de barras según Angina inducida por Ejercicio",xlab = "Angina inducida",ylab = "Frecuencias",col = "lightblue")

pie(table(data$exang),main = "Diagrama circular según Angina inducida por Ejercicio",xlab = "Angina inducida",col = c(2,3))

4 Estadística descriptiva bivariante o multivariante

4.1 Diagramas de Caja segmentado por Tipo de dolor en el pecho

4.1.1 age

En el siguiente cuadro se presentan los diagramas de caja de las edades de los pacientes vs el tipo de dolor en el pecho. En general, las edades presentan medidas centrales similares (mediana), pero los pacientes con angina típica tienen edades dentro de un rango menos disperso, a diferencia, por ejemplo, de aquellos con angina atípica. Se puede concluir que no existen edades atípicas en cada grupo de pacientes.

boxplot(data$age~data$cp,main="Diagrama de Caja por Edades",xlab = "Tipo de Dolor en el Pecho",
        ylab = "Edades",col=2)

4.1.2 trestbps

En el siguiente cuadro se presentan los diagramas de caja de la Presión Arterial de los pacientes vs el tipo de dolor en el pecho. En general, los niveles de presión arterial de los pacientes con angina típica presentan un nivel ligeramente mayor de presión arterial que los demás. Además, aquellos pacientes con angina atípica tienen niveles de presión arterial más estables que el resto de pacientes, es decir, los datos no están muy dispersos. Finalmente, se puede concluir que, a excepción de los pacientes con angina típica, el resto presenta niveles de presión arterial son atípicamente mayores.

boxplot(data$trestbps~data$cp,main="Diagrama de Caja por Presión Arterial",xlab = "Tipo de Dolor en el Pecho",
        ylab = "Presión Arterial",col=3)

4.1.3 chol

En el siguiente cuadro se presentan los diagramas de caja del Nivel de Colesterol de los pacientes vs el tipo de dolor en el pecho. En general, los niveles de colesterol de los pacientes presentan un mismo nivel de colesterol en todos los grupos. Además, aquellos pacientes que no presentan dolor en el pecho tienen niveles de colesterol menos estables que el resto de pacientes, es decir, los datos están más dispersos. Finalmente, se puede concluir que los pacientes con dolor no anginoso y sin dolor en el pecho presentan niveles de colesterol atípicamente mayores.

boxplot(data$chol~data$cp,main="Diagrama de Caja por Nivel de Colesterol",xlab = "Tipo de Dolor en el Pecho",
        ylab = "Nivel de Colesterol",col=4)

4.1.4 thalach

En el siguiente cuadro se presentan los diagramas de caja del Máximo Ritmo Cardíaco de los pacientes por cada uno del tipo de dolor en el pecho. En general, el ritmo cardíaco de los pacientes sin dolor en el pecho presentan un ritmo cardíaco ligeramente menor al del resto de los pacientes, pero también presentan una mayor inestabilidad que el de los demás, es decir, que tienen una mayor dispersión. Finalmente, se puede concluir que, a excpeción de los pacientes con angina típica, presentan ritmos cardiacos atípicamente menores para sus respectivos grupos.

boxplot(data$thalach~data$cp,main="Diagrama de Caja según Máximo Ritmo Cardiaco",xlab = "Tipo de Dolor en el Pecho",
        ylab = "Ritmo Cardiaco",col=5)

4.2 Matriz de correlación y covarianzas

En las siguientes matrices se presentan las correlaciones y covarianzas de las variables cuantitativas. Se puede ver que el máximo ritmo cardíaco tiene una relación lineal negativa con las demás variables, es decir, por ejemplo, que a medida que un paciente tiene un mayor nivel de colesterol se espera que el ritmo cardiaco disminuya. Por otro lado, los demás pares de variables tienen una relación lineal positiva, es decir, que a medida que la edad de un paciente aumenta se espera que su presión arterial también aumente.

En general, todos los pares de variables tienen una correlación débil, siendo la edad y el ritmo cardíaco la que más se destaca entre las demás, con un coeficiente de -0.39.

correlacion <- cor(data[,c(1,4,5,8)])
data.frame(correlacion)
##                 age    trestbps         chol      thalach
## age       1.0000000  0.28494592  0.208950270 -0.393805806
## trestbps  0.2849459  1.00000000  0.130120108 -0.045350879
## chol      0.2089503  0.13012011  1.000000000 -0.003431832
## thalach  -0.3938058 -0.04535088 -0.003431832  1.000000000
data.frame(cov(data[,c(1,4,5,8)]))
##                age  trestbps        chol    thalach
## age       81.69742  45.32868   97.787489 -81.423065
## trestbps  45.32868 309.75112  118.573339 -18.258005
## chol      97.78749 118.57334 2680.849190  -4.064651
## thalach  -81.42307 -18.25800   -4.064651 523.265775

4.3 Matriz gráfica de correlación

corrplot(correlacion,method = "square",type = "upper")

4.4 Matriz de diagramas de dispersión

A continuación, se presenta la matriz de diagramas de dispersión con todos los pares de variables cuantitativas para entender la relación que éstas tienen entre sí.

Se puede ver que en la mayoría de casos se forma una nube de puntos, es decir que los datos se encuentran muy dispersos y no siguen una tendencia notable. De manera particular, la edad y el máximo ritmo cardíaco se pueden ajustar, aunque con mucha dispersión, a una recta con pendiente negativa.

splom(~data[,c(1,4,5,8)],main = "Matriz de diagrama de dispersión")