Pada artikel ini, kita akan melakukan analisis eksploratif pada dataset Pokemon. Pokemon merupakan dataset yang berisikan karakteristik pokemon seperti: nama pokemon, jenis pokemon, dan karakteristik kekuatan pokemon.
Kolom-kolom pada dataset tersebut, antara lain:
number : nomor seri pokemonname : nama pokemontype : jenis pokemontotal : total nilai karakteristik serangan, kecepatan, health point, dan pertahanan pokemonhp : health pointattack : Kekuatan serangandefense : kekuatan pertahananspecial_attack : kekuatan serangan khususspecial_defense : kekuatan pertahanan khususspeed : tingkat kecepatanif(!require(tidyverse)) install.packages("tidyverse")
if(!require(skimr)) install.packages("skimr")
if(!require(DataExplorer)) install.packages("DataExplorer")
library(tidyverse)
library(skimr)
library(DataExplorer)
Terdapat tiga buah library yang diperlukan dalam tutorial ini, antara lain:
tidyverse : koleksi paket R yang dirancang untuk ilmu data. Semua paket berbagi filosofi desain, tata bahasa, dan struktur data yang mendasarinya.skimr : menyediakan fungsi untuk membuat ringkasan data yang dapat dibaca secara cepat.DataExplorer : menyediakan fungsi yang dapat membantu proses otomasi analisis data eksploratifData yang kita miliki memiliki format .csv. Untuk megimport data tersebut, kita dapat menggunakan fungsi read_csv dari library readr.
pokemon <- read_csv("data/pokemon.csv")
Untuk mengecek 10 observasi awal dataset tersebut, jalankan sintaks berikut:
pokemon
Output yang dihasilkan adalah berupa tampilan tabel ringkas yang memperlihatkan hanya 10 baris teratas dari total sebanyak 1168 baris dan menampilkan kolom 1-7 dari 10 kolom yang ada pada dataset.
selain menggunakan cara sebelumnya, kita juga dapat melihat sekilas struktur dataset dengan menggunakan fungsi glimse().
glimpse(pokemon)
## Rows: 1,168
## Columns: 10
## $ number <chr> " 001", " 001", " 002", " 002", " 003", " 003", " 003…
## $ name <chr> "Bulbasaur", "Bulbasaur", "Ivysaur", "Ivysaur", "Venu…
## $ type <chr> "GRASS", "POISON", "GRASS", "POISON", "GRASS", "POISO…
## $ total <dbl> 318, 318, 405, 405, 525, 525, 625, 625, 309, 405, 534…
## $ hp <dbl> 45, 45, 60, 60, 80, 80, 80, 80, 39, 58, 78, 78, 78, 7…
## $ attack <dbl> 49, 49, 62, 62, 82, 82, 100, 100, 52, 64, 84, 84, 130…
## $ defense <dbl> 49, 49, 63, 63, 83, 83, 123, 123, 43, 58, 78, 78, 111…
## $ special_attack <dbl> 65, 65, 80, 80, 100, 100, 122, 122, 60, 80, 109, 109,…
## $ special_defense <dbl> 65, 65, 80, 80, 100, 100, 120, 120, 50, 65, 85, 85, 8…
## $ speed <dbl> 45, 45, 60, 60, 80, 80, 80, 80, 65, 80, 100, 100, 100…
Berdasarkan dari output glimpse(pokemon) terlihat bahwa dataset pokemon terdapat sebanyak 1168 observasi dengan 10 variable (kolom). Dari 10 variable yang ada, terdapat 3 variable kategorik yaitu number, name, dan type, kemudian 7 variable lainnya bertipe numerik (dbl) yaitu total, hp, attack, defense, special attack, special defense, dan speed.
Selanjutnya, kita lakukan summary terhadap data pokemon tersebut, dengan menggunakan fungsi summary(). Berdasarkan fungsi summary untuk variabel kategorik (number, name dan type) hanya ditampilkan beberapa informasi, sedangkan untuk ketujuh variabel kontinu ditampilkan summary statistik berubah nilai min, max, quartile, dan rata-rata.
summary(pokemon)
## number name type total
## Length:1168 Length:1168 Length:1168 Min. :180.0
## Class :character Class :character Class :character 1st Qu.:334.0
## Mode :character Mode :character Mode :character Median :453.0
## Mean :435.6
## 3rd Qu.:515.0
## Max. :780.0
## hp attack defense special_attack
## Min. : 1.00 Min. : 5.00 Min. : 5.00 Min. : 10.00
## 1st Qu.: 50.00 1st Qu.: 55.00 1st Qu.: 50.00 1st Qu.: 50.00
## Median : 66.00 Median : 75.00 Median : 70.00 Median : 65.00
## Mean : 69.53 Mean : 78.82 Mean : 74.37 Mean : 72.62
## 3rd Qu.: 82.00 3rd Qu.:100.00 3rd Qu.: 90.00 3rd Qu.: 95.00
## Max. :255.00 Max. :190.00 Max. :230.00 Max. :194.00
## special_defense speed
## Min. : 20.00 Min. : 5.00
## 1st Qu.: 50.00 1st Qu.: 47.00
## Median : 70.00 Median : 65.50
## Mean : 71.72 Mean : 68.59
## 3rd Qu.: 90.00 3rd Qu.: 90.00
## Max. :230.00 Max. :180.00
Opsi lain untuk melakukan summary terhadap data set yang akan kita analisa adalah dengan menggunakan fungsi skim() dari skimr. Summary data yang dihasilkan pun lebih lengkap dari sekadar menggunakan fungsi summary ().
skim(pokemon)
| Name | pokemon |
| Number of rows | 1168 |
| Number of columns | 10 |
| _______________________ | |
| Column type frequency: | |
| character | 3 |
| numeric | 7 |
| ________________________ | |
| Group variables | None |
Variable type: character
| skim_variable | n_missing | complete_rate | min | max | empty | n_unique | whitespace |
|---|---|---|---|---|---|---|---|
| number | 0 | 1 | 4 | 6 | 0 | 772 | 0 |
| name | 0 | 1 | 3 | 26 | 0 | 773 | 0 |
| type | 0 | 1 | 3 | 8 | 0 | 18 | 0 |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| total | 0 | 1 | 435.63 | 116.53 | 180 | 334 | 453.0 | 515 | 780 | ▃▆▇▂▁ |
| hp | 0 | 1 | 69.53 | 24.92 | 1 | 50 | 66.0 | 82 | 255 | ▃▇▁▁▁ |
| attack | 0 | 1 | 78.82 | 31.71 | 5 | 55 | 75.0 | 100 | 190 | ▂▇▆▂▁ |
| defense | 0 | 1 | 74.37 | 30.76 | 5 | 50 | 70.0 | 90 | 230 | ▃▇▂▁▁ |
| special_attack | 0 | 1 | 72.62 | 31.77 | 10 | 50 | 65.0 | 95 | 194 | ▅▇▅▂▁ |
| special_defense | 0 | 1 | 71.72 | 27.27 | 20 | 50 | 70.0 | 90 | 230 | ▇▇▂▁▁ |
| speed | 0 | 1 | 68.59 | 28.32 | 5 | 47 | 65.5 | 90 | 180 | ▃▇▆▁▁ |
Hal yang berbeda adalah adanya summary data secara keseluruhan, lalu untuk variabel kategorik ditampilkan nilai min, max, jumlah observasi unik. Sedangkan untuk variabel kontinu ditampilkan pula plot histogram kecil yang semuanya dibagi menjadi 5 kelas dan hal ini juga menjadi kekurangan namun cukup informatif untuk sekadar fungsi summary().
plot_intro(pokemon)
Berdasarkan fungsi plot_intro() kita memperoleh informasi awal berupa ringkasan mengenai kondisi dataset, mencakup berapa persentase kolom (variable) yang bertipe kontinu atau diskrit, persentase berapa kolom yang memiliki missing value, dan berapa persen baris yang memiliki missing value. Diketahui sebanyak 30% kolom di dataset merupakan variable diskrit (kategorik) dan sebanyak 70% adalah variable kontinu. Baris yang terisi penuh adalah 100% menunjukkan tidak ada baris yang terisi sebagian atau kosong.
plot_missing(pokemon)
Summary dataset tentang keberadaan missing value pada tiap variable ditegaskan lagi dari hasil summary menggunakan fungsi plot_missing(). Terlihat pada plot diatas kesepuluh variable dalam data pokemon tidak memiliki missing value.
Untuk membuat plot histogram dari variabel kontinu kita terapkan fungsi plot_histogram dengan memilih variabel yang bertipe kontinu dari datanya yaitu variabel ke-4 s.d. variabel ke-10.
plot_histogram(pokemon[,4:10])
Dari output histogram diatas terlihat bahwa ketujuh variable kontinu tidak berdistribusi normal, dengan pola histogram yang agak berbeda terlihat pada histogram untuk variabel Total dimana terlihat memiliki 2 puncak histogram, tidak seperti histogram pada variabel lain yang sekilas memiliki 1 puncak saja.
Untuk variabel yang bertipe diskrit atau kategorik juga dapat dibuat plot yang berubah grafik batang dengan menggunakan fungsi plot_bar() dan memilih 3 variabel yang berjenis diskrit.
plot_bar(pokemon[,1:3])
## 2 columns ignored with more than 50 categories.
## number: 772 categories
## name: 773 categories
Kemudian dari plot bar diatas terlihat bahwa Pokemon bertipe Water mendominasi pokemon yang ada didataset, diikuti berturut-turut oleh pokemon bertipe Normal, Flying, dan Grass sedangkan pokemon berjenis Fairy merupakan jenis pokemon yang paling sedikit didataset. Perlu diperhatikan bahwa dari tiga variabel kategorik yang diinput pada fungsi plot_bar tampak hanya muncul ouput plot untuk variabel type saja sedangkan untuk variabel number dan name tidak muncul. hal ini terjadi karena kedua variabel kategorik lain memiliki kategori yang lebih dari 50 (tepatnya 772 kategori) sehingga secara default diabaikan oleh R.
Koefisien korelasi dapat dihitung sekaligus untuk semua variabel di dataset pokemon dengan menggunakan fungsi plot_correlation().
plot_correlation(pokemon)
## 2 features with more than 20 categories ignored!
## number: 772 categories
## name: 773 categories
Berdasarkan pada plot korelasi diatas terlihat bahwa kotak yang semakin berwarna merah pekat menunjukkan bahwa korelasi yang semakin kuat dan korelasinya positif. Tampak bahwa terdapat korelasi positif antara pokemon yang memiliki kemampuan special attack dengan pokemon yang memiliki special defense, walaupun korelasinya masih lemah. menyerang juga bisa bertahan.
Kita juga bisa membuat plot dari boxplot beberapa variabel menurut jenis pokemonnya, cara dengan menerapkan fungsi plot_boxplot() dengan menspesifikasikan type nya.
plot_boxplot(pokemon, by = "type")
Dari ketujuh boxplot per variabel menurut jenis pokemon, pada variabel attack terlihat bahwa pokemon berjenis Dragon dan Fighting memiliki nilai median tertinggi. kemudian dalam hal defense, pokemon berjenis Steel memiliki nilai tertinggi.Pada variabel HP tampak antar jenis pokemon memiliki nilai yang relatif sama tidak ada yang terlalu menonjol. Pokemon yang memiliki special_attack tampak pada pokemon berjenis Psychic, sedangkan dari segi Special_defence kembali lagi pokemon Dragon tampak memiliki nilai median tertinggi dibanding jenis lain. Sehingga dapat diperoleh informasi bahwa pokemon jenis Dragon selain memiliki keunggulan dalam serangan atau Attack juga memiliki keunggulan di special defense. Dari segi kecepatan “speed” tampak dari plot diatas bahwa pokemon berjenis Electric memiliki keunggulan dalam bidang speed. Jika dilihat dari Total, pokemon berjenis Dragon kembali lagi unggul dibandingkan jenis lain, sehingga disimpulkan bahwa pokemon Dragon adalah jenis pokemon 3 in 1 karena unggul di Attack, special_defence, dan secara total.
Scatterplot untuk beberapa variabel kontinu dapat dibuat dengan menerapkan fungsi plot_scatterplot dan memilih terlebih dahulu variabel kontinu yang akan dibuat plot.
plot_scatterplot(pokemon[,4:10], by = "total")
Dari scatterplot diatas terlihat bahwa semua variabel memiliki korelasi yang positif karena plot cenderung membuat pola dari kiri bawah ke kanan atas. Selain itu tampak bahwa korelasi positif yang ada tidak terlalu kuat karena sebaran titiknya agak menyebar dan tidak sempurna membentuk garis lurus.
pokemon %>%
ggplot() +
geom_boxplot(aes(x = type, y = total)) +
coord_flip()
Dari boxplot menurut jenis pokemon, tampak bahwa Pokemon berjenis Dragon memiliki median nilai Total yang tertinggi, artinya pokemon jenis ini secara umum dapat dikatakan terkuat dari berbagai aspek (pertahanan, serangan, HP, dll)
pokemon %>%
arrange(desc(total))
Berdasarkan tabel diatas terlihat bahwa pokemon terkuat dari segi nilai Total adalah pokemon dengan nama Mega Mewtwo X dan Mega Mewtwo Y dengan nilai Total 780.
pokemon %>%
arrange(total)
Pada tabel diatas terlihat bahwa Pokemon dengan nama Surkern adalah pokemon yang terlemah jika dilihat dari variabel total dan pokemon ini berjenis Grass (pokemon rumput)
pokemon %>%
arrange(desc(speed))
Pada tabel diatas terlihat bahwa Pokemon dengan nama Deoxys- Speed Forme adalah pokemon yang terlcepat terlihat dari variabel Speed dengan nilai 180 dan pokemon ini berjenis Psychic.
Analisa sebelumnya hanya difokuskan pada satu variabel saja, agar analisa kita menjadi semakin kaya dapat dilakukan dengan mencari pokemon yang terkuat dari masing-masing jenis.
max <- pokemon %>%
group_by(type) %>%
summarise(total = max(total))
## `summarise()` ungrouping output (override with `.groups` argument)
pokemon %>%
right_join(max, by = c("type", "total"))
Pada tabel tersebut ditampilkan pokemon yang terkuat setiap jenisnya, misalkan Mega Venusaur merupakan pokemon terkuat dari jenis Grass, kemudian Mega Mewtwo X menjadi pokemon terkuat dari jenis Psychic dan jenis Fighting. Dari jenis Rock (pokemon batu), Mega Tyranitar menjadi pokemon terkuat. Pada jenis pokemon terbang (Flying), terdapat tiga pokemon yang terkuat yaitu Lugia, Ho-oh, dan Rayquaza.
Lalu bagaimana jika kita ingin melihat pokemon yang memiliki serangan spesial yang tertinggi dari tiap jenisnya? Kita lakukan grouping berdasarkan type pokemon dan analisa akan berfokus untuk mencari nilai maksimum dari special attack suatu pokemon pada tiap jenisnya.
max <- pokemon %>%
group_by(type) %>%
summarise(special_attack = max(special_attack))
## `summarise()` ungrouping output (override with `.groups` argument)
pokemon %>%
right_join(max, by = c("type", "special_attack"))
Pokemon dengan special attack tertinggi pada jenis pokemon api (fire) adalah Mega Charizard Y, sedangkan pada pokemon berjenis air (water) dengan special attack tertinggi adalah Kyogre dan Palkia. Kemudian pokemon dengan nama Mega Mewtwo Y merupakan pokemon dengan special attack tertinggi untuk tipe pokemon Psychic. Pokemon Mega Gengar adalah pokemon dengan special attack tertinggi tidak hanya pada jenis pokemon Ghost dan Poison.
Setelah membahas mengenai pokemon dengan tingkat serangan spesial tertinggi pada masing-masing jenis pokemon, nampaknya akan lebih berimbang jika kita juga membahas dari sisi pertahanan spesial (special_defense) yang dimiliki pokemon menurut jenisnya. Setiap pokemon lalu dikelompokkan menurut jenisnya, lalu dicari nilai maksimum special defense pada tiap jenis pokemon.
max <- pokemon %>%
group_by(type) %>%
summarise(special_defense = max(special_defense))
## `summarise()` ungrouping output (override with `.groups` argument)
pokemon %>%
right_join(max, by = c("type", "special_defense"))
Berdasarkan pada tabel yang dihasilkan diketahui bahwa pokemon dengan tingkat pertahanan special tertinggi untuk jenis pokemon kegelapan (Dark) adalah Mega Gyarados, sedangkan pada jenis pokemon elektrik, special defense tertinggi dimiliki oleh Mega Ampharos. Selain itu, diketahui juga bahwa pokemon dengan nama Shuckle menjadi pokemon dengan special defense tertinggi untuk pokemon berjenis Bug atau Rock.Shuckle adalah pokemon yang memiliki nilai special defense sebesar 230 termasuk yang tertinggi dibandingkan jenis pokemon lainnya.
Untuk melihat apakah pokemon yang memiliki serangan spesial tinggi akan memiliki pertahanan yang tinggi pula
ggplot(pokemon, aes(x =special_attack, y =special_defense)) +
geom_point()+
geom_smooth()
## `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'
Jika dilihat darii sebaran titik-titiknya, terlihat ada pola yang agak menyebar dan sedikit mengumpul pada nilai special_attack antara 50-100 dan nilai special_defense antara 50-100. Titik yang mengumpul menunjukkan ada hubungan antara special_attack dengan special_defense. Secara umum, sebaran titik yang menyebar ini tampak memiliki pola sebaran condong dari kiri bawah ke kanan atas, hal ini menunjukkan adanya hubungan yang positif antara special_attack dengan special_defense walaupun hubungan itu terlihat lemah karena titik-titiknya agak menyebar. Fungsi geom_smooth () dapat membantu kita dalam melihat pola dengan adanya overplotting. Fungsi geom_smooth menghasilkan output berupa garis berwarna biru dengan arsiran abu-abu disekelilingnya, garis yang berwarna biru tersebut dapat kita interpretasikan sebagai garis regresi. Garis biru (garis regresi) yang dihasilkan terlihat memiliki tren naik dari kiri bawah ke kanan atas namun dengan kemiringan yang rendah, hal ini yang menandakan bahwa terdapat hubungan yang positif tapi lemah. Dengan demikian dari interpretasi scatterplot dan garis regresi smooth dapat diduga bahwa memang ada hubungan positif yang lemah antara special_attack dengan special_defense, artinya sebagian pokemon yang memiliki serangan spesial yang tinggi juga akan memiliki tingkat pertahanan special yang tinggi.