#load("/Volumes/SP UFD U2/ProbyEst(I)-17/1617/PrimerDía/Pokemon.RData")
load("/Users/arminda/ownCloud/Prob_y_Estad/ProbyEst(I)-17/1617/PrimerDía/Pokemon.RData")
head(pokemon1)
## Name Type.1 Type.2 Total HP Attack Defense Sp..Atk Sp..Def Speed
## 1 Bulbasaur Grass Poison 318 45 49 49 65 65 45
## 2 Ivysaur Grass Poison 405 60 62 63 80 80 60
## 3 Venusaur Grass Poison 525 80 82 83 100 100 80
## 4 Charmander Fire none 309 39 52 43 60 50 65
## 5 Charmeleon Fire none 405 58 64 58 80 65 80
## 6 Charizard Fire Flying 534 78 84 78 109 85 100
## Generation Legendary
## 1 1 False
## 2 1 False
## 3 1 False
## 4 1 False
## 5 1 False
## 6 1 False
dim(pokemon1)
## [1] 721 12
str(pokemon1)
## 'data.frame': 721 obs. of 12 variables:
## $ Name : Factor w/ 800 levels "Abomasnow","AbomasnowMega Abomasnow",..: 81 330 746 103 104 100 666 765 65 96 ...
## $ Type.1 : Factor w/ 18 levels "Bug","Dark","Dragon",..: 10 10 10 7 7 7 18 18 18 1 ...
## $ Type.2 : Factor w/ 19 levels "none","Bug","Dark",..: 15 15 15 1 1 9 1 1 1 1 ...
## $ Total : int 318 405 525 309 405 534 314 405 530 195 ...
## $ HP : int 45 60 80 39 58 78 44 59 79 45 ...
## $ Attack : int 49 62 82 52 64 84 48 63 83 30 ...
## $ Defense : int 49 63 83 43 58 78 65 80 100 35 ...
## $ Sp..Atk : int 65 80 100 60 80 109 50 65 85 20 ...
## $ Sp..Def : int 65 80 100 50 65 85 64 80 105 20 ...
## $ Speed : int 45 60 80 65 80 100 43 58 78 45 ...
## $ Generation: Factor w/ 6 levels "1","2","3","4",..: 1 1 1 1 1 1 1 1 1 1 ...
## $ Legendary : Factor w/ 2 levels "False","True": 1 1 1 1 1 1 1 1 1 1 ...
Vemos que disponemos de 721 filas (pokemon diferentes) y 12 columnas (variables). ¿Cuáles de estas variables son nominales, ordinales, cuantitativas discretas y cuantitativas continuas?
Por ejemplo, la variable Type.1 es nominal, indica el tipo principal del Pokemon. Además, vemos en la salida de str() que es un factor con 18 niveles. Veamos cuáles son y cuántos pokemons hay de cada uno.
table(pokemon1$Type.1)
##
## Bug Dark Dragon Electric Fairy Fighting Fire Flying
## 63 28 24 36 17 25 47 3
## Ghost Grass Ground Ice Normal Poison Psychic Rock
## 23 66 30 23 93 28 47 41
## Steel Water
## 22 105
Vemos que el tipo más abundante es Agua, seguido de Normal. Veamos cuántos pokemon hay de cada generación.
table(pokemon1$Generation)
##
## 1 2 3 4 5 6
## 151 100 135 107 156 72
Hay más pokemon de la quinta generación. Analicemos un poco más esta generación. Voy a crear otro conjunto de datos (llamado quinta) con solo los pokemon de la quinta generación y hacemos un diagrama de barras para ver los tipos que hay.
library(dplyr)
=filter(pokemon1, Generation==5)
quintalibrary(ggplot2)
ggplot(quinta, aes(x=Type.1))+geom_bar(color="blue", fill="blue", alpha=0.6)+theme(axis.text.x=element_text(size=6))
Vemos que aquí los más abundantes son de tipo Bicho, seguido de Normal y Agua. Vamos a hacer una tabla de frecuencias de la variable Tipo para estos pokemon. Por defecto, los ordena por orden alfabético.
# con el siguiente comando, quito el Tipo 'Fairy' porque no hay ningún pokemon de este
# tipo en la Generación 5, pero sí en el resto de generaciones.
= quinta %>% filter(Type.1!='Fairy') %>% droplevels()
quinta =table(quinta$Type.1)
quintat=as.data.frame(cbind(FrecuenciaAbsoluta=quintat, FrecuenciaRelativa=round(prop.table(quintat),3)))
Tabla1$Tipo=rownames(Tabla1)
Tabla1# ordenamos los tipos en orden decreciente de frecuencia
=Tabla1[order(Tabla1$FrecuenciaRelativa, decreasing=TRUE),]
Tabla1$Tipo <- factor(Tabla1$Tipo, levels = Tabla1$Tipo[order(Tabla1$FrecuenciaAbsoluta, decreasing=TRUE)])
Tabla1-3] Tabla1[,
## FrecuenciaAbsoluta FrecuenciaRelativa
## Bug 18 0.115
## Normal 17 0.109
## Water 17 0.109
## Grass 15 0.096
## Psychic 14 0.090
## Dark 13 0.083
## Ground 9 0.058
## Fire 8 0.051
## Dragon 7 0.045
## Electric 7 0.045
## Fighting 7 0.045
## Ice 6 0.038
## Rock 6 0.038
## Ghost 5 0.032
## Steel 4 0.026
## Poison 2 0.013
## Flying 1 0.006
ggplot(Tabla1, aes(x=Tipo, y=FrecuenciaAbsoluta))+geom_bar(color="blue", fill="blue", alpha=0.6, stat='identity')+theme(axis.text.x=element_text(size=7))
Por curiosidad, veamos cuál es el pokemon tipo Volador y los dos tipo Veneno:
library(knitr)
kable(quinta[quinta$Type.1=="Flying",])
Name | Type.1 | Type.2 | Total | HP | Attack | Defense | Sp..Atk | Sp..Def | Speed | Generation | Legendary | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
148 | TornadusIncarnate Forme | Flying | none | 580 | 79 | 115 | 70 | 125 | 80 | 111 | 5 | True |
kable(quinta[quinta$Type.1=="Poison",])
Name | Type.1 | Type.2 | Total | HP | Attack | Defense | Sp..Atk | Sp..Def | Speed | Generation | Legendary | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
75 | Trubbish | Poison | none | 329 | 50 | 50 | 62 | 40 | 62 | 65 | 5 | False |
76 | Garbodor | Poison | none | 474 | 80 | 95 | 82 | 60 | 82 | 75 | 5 | False |
Vamos a estudiar ahora la variable HP de la 5ª Generación. Para hacer una tabla de frecuencias, vemos el rango de los datos:
summary(quinta$HP)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 30.00 55.00 70.00 70.19 80.00 165.00
El mínimo es \(30\) y el máximo es \(165\). Voy a crear \(7\) intervalos comenzando en \(25\) y terminando en \(175\), (\([25,50),[50,75),\dots\)). La amplitud de cada intervalo será de \(25\) unidades.
=cut(quinta$HP, breaks=seq(25,175,by=25),right=F)
hp_cut=table(hp_cut)
table_hp=as.data.frame(table_hp)
table_hpcolnames(table_hp)=c("Clase","FrecAbs")
=table_hp %>% mutate(FrecAbsAc=cumsum(FrecAbs),FrecRel=round(prop.table(table_hp$FrecAbs),5), FreRelAc=cumsum(FrecRel))
Tabla_HP Tabla_HP
## Clase FrecAbs FrecAbsAc FrecRel FreRelAc
## 1 [25,50) 21 21 0.13462 0.13462
## 2 [50,75) 73 94 0.46795 0.60257
## 3 [75,100) 42 136 0.26923 0.87180
## 4 [100,125) 18 154 0.11538 0.98718
## 5 [125,150) 1 155 0.00641 0.99359
## 6 [150,175) 1 156 0.00641 1.00000
En la tabla vemos que el \(87\%\) de los pokemon de la 5ª generación tienen menos de \(100\) HP y el \(98.7\%\) menos de \(125\). También, el \(60\%\) tienen menos de \(65\) HP. Podríamos pensar que son Pokemon debiluchos, pero como veremos después, la distribución de HP es similar para todas las generaciones.
Para obtener un histograma de una variable cuantitativa tecleamos lo siguiente. Por defecto, el programa elige el número de intervalos o clases a dibujar. Si queremos especificar nosotros el número, usamos el parámetro bins.
ggplot(quinta, aes(x=HP))+geom_histogram(fill="blue", colour="white",closed="left", bins=12)
Si queremos usar las mismas clases que usamos antes en la tabla de frecuencias, las definimos expresamente de la siguiente forma:
ggplot(quinta, aes(x=HP))+geom_histogram(breaks=seq(25,175,by=25), closed="left", colour="white", fill="blue")
Vemos que la mayor parte de pokemon tienen un HP menor que \(75\) (un \(60\%\)) o menor que \(100\) (un \(87\%\)). La distribución de frecuencias tiene la joroba un poco hacia la izquierda, con lo que presenta una muy ligera asimetría a la derecha (o positiva). Veamos cuáles son los pokemon con más \(HP\):
library(knitr)
kable(quinta[quinta$HP>=125,])
Name | Type.1 | Type.2 | Total | HP | Attack | Defense | Sp..Atk | Sp..Def | Speed | Generation | Legendary | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
101 | Alomomola | Water | none | 470 | 165 | 75 | 80 | 40 | 45 | 65 | 5 | False |
153 | Kyurem | Dragon | Ice | 660 | 125 | 130 | 90 | 130 | 90 | 95 | 5 | True |
Son Alomomola (No Legendario) y Kyuren (Legendario).
Con el diagrama de tallo-hojas recuperamos la forma del histograma pero, a la vez, vemos los datos individuales.
stem(quinta$HP)
##
## The decimal point is 1 digit(s) to the right of the |
##
## 3 | 0568
## 4 | 00001455555555556
## 5 | 000000000000012455555555555889
## 6 | 00000000000002245555555679
## 7 | 0000000000011224455555555555555566799
## 8 | 000055555599
## 9 | 0111125555
## 10 | 00000035559
## 11 | 000046
## 12 | 05
## 13 |
## 14 |
## 15 |
## 16 | 5
ggplot(quinta, aes(x=HP, y=HP))+geom_boxplot(outlier.colour = "red", outlier.shape = 1)
Vemos los tres datos atípicos que identificamos antes, los pokemon con más valor de HP y la leve asimetría. También vemos que la anchura de la caja es pequeña (\(Q_3-Q_1=80-55=25\)) comparado con el rango de los datos \(\min-\max=165-30=135\), con lo que la distribución es más picuda que la Normal, es Leptocúrtica.
$Generation=as.factor(pokemon1$Generation)
pokemon1ggplot(pokemon1, aes(x=Generation, y=HP))+geom_boxplot(outlier.colour = "red", outlier.shape = 1)
A priori no hay razones para creer que la mediana de HP es distinta a través de las distintas Generaciones de pokemon. Eso sí, los pokemon con mayor valor de HP están en la primera y segunda generación y el que tiene menor valor de HP es de la tercera. En el siguiente gráfico hemos añadido los datos encima de los boxplot y los hemos coloreado según sean o no legendarios. Así vemos que ninguno de los pokemon con mayor o menor valor de HP son Legendarios.
$Generation=as.factor(pokemon1$Generation)
pokemon1ggplot(pokemon1, aes(x=Generation, y=HP))+geom_boxplot(outlier.colour = "red", outlier.shape = 1)+geom_jitter(aes(color=Legendary), alpha=0.6)
library(kableExtra)
=addmargins(table(pokemon1$Generation,pokemon1$Legendary))
pruebarownames(prueba)=c("Gen 1","Gen 2","Gen 3", "Gen 4", "Gen 5", "Gen 6", "Suma")
colnames(prueba)=c("NoLeg.", "Leg.", "Suma")
%>% kable("html") %>% kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width=F) prueba
NoLeg. | Leg. | Suma | |
---|---|---|---|
Gen 1 | 147 | 4 | 151 |
Gen 2 | 95 | 5 | 100 |
Gen 3 | 125 | 10 | 135 |
Gen 4 | 96 | 11 | 107 |
Gen 5 | 146 | 10 | 156 |
Gen 6 | 66 | 6 | 72 |
Suma | 675 | 46 | 721 |
A partir de esta tabla, es fácil estudiar las distribuciones marginales y condicionadas, ya que vuelven a ser distribuciones univariantes.