PENGANTAR

Postingan ini adalah edisi spesial. Aha. Spesial persiapan Ujian Tengah Semester mata kuliah analisis data eksplorasi. Yashhh. Selama setengah semester ini banyak banget yang dibahas, mulai dari summary statistik yg meliputi mean, median dll, terus ada visualisasi data menggunakan ggplot2, terus ada subset data dll. Postingan ini dibuat saat mengisi masa-masa gabut ngerjain skripsi xD. Oke masuk ke materi! Outlinenya : summary statistics, subsetting data, vizualitation with ggplot2 & lattice packages.

MEMBANGKITKAN DATA

Karena bingung mau ambil sumber data darimana, jadi saya kepikiran buat membangkitkan data aja ya.. jadi data ini bukan hasil survey melainkan simulasi aja hehe. Kasus yang diambil terdiri dari 7 variabel, antara lain : jenis kelamin, kelas, pengeluaran tiap hari, jarak kamus dengan tempat tinggal (km), status organisasi, waktu belajar per minggu, nilai akhir.

setwd("E:\\AKADEMIK\\Belajar R\\UTS ADE")

################ generete data
rtnorm <- function(n, mean, sd, a = -Inf, b = Inf){
  qnorm(runif(n, pnorm(a, mean, sd), pnorm(b, mean, sd)), mean, sd)
}

set.seed(1)
nilai <- rtnorm(n=160, mean=82, sd=100, a=60, b=100)
set.seed(2)
jarak <- rtnorm(n=160, mean=5, sd=100, a=0.5, b=15)
set.seed(3)
waktu.belajar <- rtnorm(n=160, mean=15, sd=100, a=0, b=21)
kelas <- rep(c("a","b","c","d"), each = 40)
set.seed(4)
jk <- sample(factor(c(rep("perempuan",0.6*160), rep("laki-laki",0.4*160))))
set.seed(5)
pengeluaran <- sample(factor(c(rep("50k",0.6*160), rep("100k",0.35*160), rep("150k",0.05*160))))
set.seed(6)
organisasi <- sample(factor(c(rep("ya",0.3*160), rep("tidak",0.7*160))))

data.simu <- data.frame(jk,kelas,pengeluaran,jarak,organisasi,waktu.belajar,nilai)
write.csv(data.simu, file = "datasimulasiuts.csv", row.names = FALSE)

Perintah setwd() adalah untuk megatur direktori kerja yang akan digunakan. Penjelasan lengkapnya sudah dibahas di materi ini Direktori Kerja R. Kemudian saya membuat fungsi untuk membangktkann data berdistribusi normal dengan batas bawah dan batas atas yang disimbolkan hurup a dan b. Karena kita membangkitkan data secara acak, maka perintah set.seed penting digunakan untuk memberikan hasil yang konsisten. Jika tidak menggunakan perintah tersebut, hasil yang akan keluar selalu berbeda setiap kali di eksekusi. tidak ada aturan khusus atau efek saat menentukan nilai seed. Jika perintah diatas dieksekusi hingga selesai, maka akan data akan tersimpan pada direktori kerja yang telah kita atur diawal. Untuk meminimalisir kebingungan, teman-teman dapat juga mengunduh file tersebut di tautaan ini download data.

STATISTIKA DESKRIPTIF

Pada bagian ini akan dibahas ringkasan hasil statistika deskriptif. Menggunakan packages Hmisc dan base.

library(Hmisc)
data <- read.csv("E:\\AKADEMIK\\Belajar R\\UTS ADE\\datasimulasiuts.csv", header = TRUE, sep = ",")
attach(data)
str(data) #Melihat struktur bentuk data
## 'data.frame':    160 obs. of  7 variables:
##  $ jk           : Factor w/ 2 levels "laki-laki","perempuan": 2 2 2 2 1 2 1 1 1 2 ...
##  $ kelas        : Factor w/ 4 levels "a","b","c","d": 1 1 1 1 1 1 1 1 1 1 ...
##  $ pengeluaran  : Factor w/ 3 levels "100k","150k",..: 3 1 1 3 3 2 3 1 1 2 ...
##  $ jarak        : num  3.18 10.68 8.81 2.94 14.18 ...
##  $ organisasi   : Factor w/ 2 levels "tidak","ya": 1 1 2 1 1 1 1 1 1 2 ...
##  $ waktu.belajar: num  3.55 16.97 8.11 6.91 12.66 ...
##  $ nilai        : num  70.7 75 82.9 96.3 68.1 ...
dim(data) #Melihat dimensi data antara baris dan kolomnya
## [1] 160   7
head(data) #Melihat 6 data teratas, lawan perintahnya yaitu tail()
##          jk kelas pengeluaran     jarak organisasi waktu.belajar    nilai
## 1 perempuan     a         50k  3.178853      tidak      3.549938 70.70007
## 2 perempuan     a        100k 10.676233      tidak     16.965856 74.95376
## 3 perempuan     a        100k  8.805257         ya      8.111441 82.93399
## 4 perempuan     a         50k  2.935073      tidak      6.910114 96.30527
## 5 laki-laki     a         50k 14.182938      tidak     12.664042 68.14421
## 6 perempuan     a        150k 14.177639      tidak     12.712079 95.91133
#deskriptif
summary(data) #packages base
##          jk     kelas  pengeluaran     jarak         organisasi 
##  laki-laki:64   a:40   100k:56     Min.   : 0.6031   tidak:112  
##  perempuan:96   b:40   150k: 8     1st Qu.: 3.9838   ya   : 48  
##                 c:40   50k :96     Median : 6.9005              
##                 d:40               Mean   : 7.6235              
##                                    3rd Qu.:11.6936              
##                                    Max.   :14.8385              
##  waktu.belajar         nilai      
##  Min.   : 0.1814   Min.   :60.53  
##  1st Qu.: 4.7972   1st Qu.:70.86  
##  Median : 9.8364   Median :79.82  
##  Mean   :10.0439   Mean   :80.16  
##  3rd Qu.:15.9020   3rd Qu.:88.75  
##  Max.   :20.8578   Max.   :99.70
describe(data) #packages Hmisc
## data 
## 
##  7  Variables      160  Observations
## ---------------------------------------------------------------------------
## jk 
##        n  missing distinct 
##      160        0        2 
##                               
## Value      laki-laki perempuan
## Frequency         64        96
## Proportion       0.4       0.6
## ---------------------------------------------------------------------------
## kelas 
##        n  missing distinct 
##      160        0        4 
##                               
## Value         a    b    c    d
## Frequency    40   40   40   40
## Proportion 0.25 0.25 0.25 0.25
## ---------------------------------------------------------------------------
## pengeluaran 
##        n  missing distinct 
##      160        0        3 
##                          
## Value      100k 150k  50k
## Frequency    56    8   96
## Proportion 0.35 0.05 0.60
## ---------------------------------------------------------------------------
## jarak 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      160        0      160        1    7.623    4.934    1.438    2.371 
##      .25      .50      .75      .90      .95 
##    3.984    6.900   11.694   13.623   14.478 
## 
## lowest :  0.6030539  0.6509692  0.7130004  0.8306769  0.8574029
## highest: 14.6617415 14.6927270 14.7176833 14.7340945 14.8384902
## ---------------------------------------------------------------------------
## organisasi 
##        n  missing distinct 
##      160        0        2 
##                       
## Value      tidak    ya
## Frequency    112    48
## Proportion   0.7   0.3
## ---------------------------------------------------------------------------
## waktu.belajar 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      160        0      160        1    10.04    6.749    1.672    2.352 
##      .25      .50      .75      .90      .95 
##    4.797    9.836   15.902   17.826   18.857 
## 
## lowest :  0.1814002  0.2486604  0.3245665  0.8152738  0.8713156
## highest: 19.1846836 19.3453959 20.0631500 20.2928222 20.8578159
## ---------------------------------------------------------------------------
## nilai 
##        n  missing distinct     Info     Mean      Gmd      .05      .10 
##      160        0      160        1    80.16    12.33    63.12    65.22 
##      .25      .50      .75      .90      .95 
##    70.86    79.82    88.75    94.78    97.14 
## 
## lowest : 60.53195 60.54467 60.94861 61.44426 62.39256
## highest: 99.03869 99.39853 99.67057 99.67330 99.70469
## ---------------------------------------------------------------------------

Perintah read.csv adalah untuk memanggil data file eksetensi comma separated value. Pembahasannya sudah ada di materi Direktori Kerja R. attach() berfungsi untuk melampirkan variabel yang terdapt pada data. Sehingga objek dalam basis data dapat diakses hanya dengan memanggil nama variabel nya saja, tidak perlu menggunakan simbol $.

Perbedaan hasil pada perintah summary() dan describe() terletak pada fitul keluaran yang dihasilkan. jika pada describe() memungkinkan peneliti untuk mengetahui informasi data kategoriknya secara mendetail menurut proporso masing-masing. Selain itu untuk data numerik keluaran yang dihasilkan pun lebih lengkap dibandingkan dengan perintah summary().

SUBSETTING DATA

#hitung rata-rata nilai mahasiswa untuk kelas d yang jarak tempat tinggalnya lebih dari 5km!
solve_1 <- subset(data, kelas == "d" & jarak > 5)
summary(solve_1)
##          jk     kelas  pengeluaran     jarak        organisasi
##  laki-laki:11   a: 0   100k: 5     Min.   : 5.015   tidak:18  
##  perempuan:13   b: 0   150k: 3     1st Qu.: 6.767   ya   : 6  
##                 c: 0   50k :16     Median :10.162             
##                 d:24               Mean   : 9.788             
##                                    3rd Qu.:12.482             
##                                    Max.   :14.693             
##  waktu.belajar        nilai      
##  Min.   : 2.087   Min.   :63.13  
##  1st Qu.: 5.405   1st Qu.:72.33  
##  Median :11.326   Median :80.20  
##  Mean   :10.584   Mean   :78.54  
##  3rd Qu.:15.029   3rd Qu.:82.80  
##  Max.   :18.656   Max.   :97.12
mean(solve_1$nilai)
## [1] 78.54488

Pada kasus pertama diminta untuk menghitung rata-rata nilai mahasiswa kelas d yang jarak tempat tinggalnya lebih dari 5km. Maka perlu dilakukan pemilahan data terlebih dahulu sesuai dengan kondisi yang diminta. Karena bentuk data variabel kelas factor dengan labels a, b, c, d sehingga jangan lupakan tanda "" ketika memilih nilainya. Lain halnya ketika datanya numerik, tidak perlu menggunakan tanda "". Untuk menambahkan kondisi selanjutnya cukup menggunakan tanda & hal tersebut berlaku ketika ingin menambah kondisi selanjutnya. Berdasarkan hasil diperoleh nilai rata-rata mahasiswa kelas d yang jarak tempat tinggalnya lebih dari 5km adalah 78.54488.

#hitung rata-rata nilai mahasiswa yang aktif organisasi dengan jarak tempat tinggalnya kurang dari 5km dan pengeluaran perharinya 50k!
solve_2 <- subset(data, organisasi == "ya" & jarak < 5 & pengeluaran == "50k")
mean(solve_2$nilai)
## [1] 81.37008

Contoh kasus diatas adalah apabila kondisi yang diminta lebih dari 2.

VISUALISASI DENGAN LATTICE

#gambarkan boxplot berdasarkan status organisasi dan nilai mahasiswa tiap kelas yang memiliki pengeluaran per hari sebanyak 50k!
solve_3 <- subset(data, pengeluaran == "50k")
library(lattice)
bwplot(nilai~organisasi| kelas, data=solve_3, layout = c(4,1), xlab="organisasi", ylab = "nilai")

Kasus selanjutny yaitu diminta untuk membuat box plot berdasarkan status organisasi dan nilai mahasiswa tiap kelas yang memiliki pengeluaran per hari sebanyak 50k. Maka langkah awal yaitu melakukan subsetting data. Kondisi yang diminta yaitu mahasiswa dengan pengeluaran 50k per harinya. Selanjutnya menggunakan perintah bwplot untuk membuat boxplot packages lattice. Formulanya yaitu y~x maka kasus diatas yang menjadi variabel y adalah nilai mahasiswa, dan variabel x adalah status organisasi. Sesuai dengan perintah untuk membuat grafik tiap kelas maka perintah atau simbol yang digunakan yaitu | kelas fungsinya sebagai pemisah antar kelompok. Perintah layout() untuk menampilkan hasil grafik ke dalam bentuk (baris,kolom). Periintah xlab untuk memberi judul sumbu x dan ylab untuk judul sumbu y.

#gambarkan histogram nilai mahasiswa berdasarkan jarak tempat tinggalnya yang lebih dari 5km!
solve_4 <- subset(data, jarak > 5)
histogram(~nilai, data = solve_4)

Kasus selanjutnya diminta untuk membuat histogram nilai mahasiswa berdasarkan waktu belajar yang lebih dari 12 jam perminggunya. Perintah membuat histogram pada packages lattice dengan cara histogram(~x).

#gambarkan plot densitas nilai mahasiwa tiap kelas yang aktif organisasi! (interpretasikan)
solve_5 <- subset(data, organisasi == "ya")
densityplot(~nilai, groups = kelas, data = solve_5, plot.points = F, auto.key = T)

#gambarkan scatterplot nilai mahasiswa tiap kelas dan jarak tempat tinggal yang memiliki pengeluaran per hari sebesar 100k! gunakan batas sumbu x 5 hingga 15km!
solve_6 <- subset(data, pengeluaran == "50k")
xyplot(nilai~jarak | kelas, data = solve_6, groups = kelas, auto.key = T, type = c("p","smooth"), layout = c(4,1), xlim = c(5,15))

VISUALISASI DENGAN GGPLOT2

#gambarkan boxplot berdasarkan status organisasi dan nilai mahasiswa tiap kelas yang memiliki pengeluaran per hari sebanyak 50k! (interpretasi hasilnya)
solve_7 <- subset(data, pengeluaran == "50k")
library(ggplot2)
graf_7 <- ggplot(solve_7, aes(x=organisasi,y=nilai))
graf_7 + geom_boxplot(aes(fill=kelas))+
  theme_classic() +
  labs(title= "Box plot",
       subtitle="nilai mahasiswa berdasarkan status keorganisasian",
       x = "Status Organisasi",
       y = "nilai mahasiswa")

Sesuai perintaah diatas, maka sebelum membuat grafik box plot terlebih dahulu dilakukan subsetting data. Permintaannya yaitu untuk mahasiswa yang biaya pengeluaran perhari sebanyak 50k. Perintah ggplot()untuk menginsisiasi objek ggplot. artinya perintah tersebut dapat digunakan untuk menyatakan frame data input pada grafik. pada kasus diatas yang menjadi sumbu x adalah status organisasi dan sumbu y yaitu nilai mahasiswa. geom_boxplot perintah untuk membuat grafik boxplot yang memuat informasi Q1, Q2 (median), Q3, whisker, dan outlier. fill = kelas digunakan sebagai membedakan warna berdasarkan kategori kelas. Perintah labs untuk labeling judul, subtitel, sumbu x dan sumbu y.

interpretasi : Secaara visual pada kelas A, kelompok yang tidak ikut organisasi nampak terlihat interquartile (Q3-Q1) lebih luas dibandingkan dengan yang aktif berorganisasi. Maka dapat dikatakan data nilai mahasiswa yang tidak aktif berorganisasi lebih bervariasi. Median kelas A mahasiswa yang tidak aktif berorganisasi (80) lebih tinggi dibandingkan dengan yang aktif organisasi (sekitar 76). Pada kelas D terdapat data pencilan di mahasiswa yang tidak aktif berorganisasi. Hal tersebut mengindikasi terdapat 3 mahasiswa yang tidak aktif berorganisasi memiliki nilai yang jauh dibandingkan dengan mahasiswa lainnya (tidak aktif organisasi).

#gambarkan histogram nilai mahasiswa berdasarkan jarak tempat tinggalnya yang lebih dari 5km! (interpretasikan)
solve_8 <- subset(data, jarak > 5)
graf_8 <- ggplot(solve_8, aes(nilai))
graf_8 + geom_histogram(bins = 10, col = "black", fill = "brown") +
  theme_classic() +
  labs(title="histogram",
       subtitle="nilai mahasiswa dengan tempat tinggal lebih dari 5km",
       x = "nilai mahasiswa",
       y = "frekuensi")

Histogram adalah tampilan bentuk grafis untuk menunjukkan secara visual seberapa sering suatu nilai yang berbeda terjadi dalam range kumpulan data. Pada kasus di atas yang ingin dilihat yaitu histogram nilai mahasiswa dengan syarat yang memiliki jarang tempat tinggal lebih dari 5km. Sebelumnya, dilakukan subsetting data untuk mahasiswa yang mempunyai tempat tinggal lebih dari 5km. Kemudian perintah geom_histogram adalah untuk membuat historam pada packages ggplot2. untuk menentukan jumlah kelas histogram menggunakan perintah bins = Sesuai dengan jumlah data yang yang lebih dari 150, maka digunakan jumlah kelas histogram antara 10 hingga 12. Jika data kurang dari 50 maka kelas ideal yang terbentuk adalah 5 hingga 7 data.

interpretasi : Dapat diperoleh simpulan berdasarkan visualisasi rentang mahasiswa yang memiliki nilai 59 hingga 63 adalah sebanyak 4 mahasiswa. Sedangkan yang paling banyak yaitu berada di rentang nilai 76 hingga 81 dengan frekuensi sebanyak 20 kali. Jika dilihat secara kasat mata, sudah membentuk garis distribusi normal.

#gambarkan plot densitas nilai mahasiwa tiap kelas yang aktif organisasi! (interpretasikan)
solve_9 <- subset(data, organisasi == "ya")
graf_9 <- ggplot(solve_9, aes(nilai))
graf_9 + geom_density(aes(group=kelas, fill=kelas), alpha = 0.6) +
theme_classic() +
  labs(title="Plot densitas",
       subtitle="nilai mahasiswa yang aktif organisasi berdasarkan kelas",
       x = "nilai mahasiswa",
       y = "densitas")

Mirip dengan histogram, plot densitas berfungsi untuk menunjukkan sebaran distribusi data. Perintah untuk membuat plot densitas di packages ggplot2 adalah geom_density. Kemudian perintah alpha = untuk mengatur estetika ketebalan warna dari plot densitas yang terbentuk.

interpretasi = Pada keluaran grafik diatas dapat menjadi asumsi melihat sebaran distribusi data nilai mahasiswa tiap kelas. Dikatakan berdistribusi normal jika grafik berbentuk gunung dimana puncaknya berada ditengah. Kemudian asymptotic atau ujung-ujung garisnya tidak menyentuh sumbu horizontal sehingga batas ujungnya tidak ada atau tidak hingga. Nilai mahasiswa kelas A secara grafik terlihat membentuk distribusi bimodal. karena mempunya 2 puncak atau terdapat 2 objek yang frekuensinya besar. Berada disekitar nilai 65 dan 80. Kemudian pada mahasiswa kelas B mengalami skew ke kiri karena ekor (tail) landai ke sumbu negatif. Hal tersebut dikarenakan frekuensi nilai mahasiswa kelas B cenderung tinggi sehingga membentuk distribusi serong ke kiri. Pada nilai mahasiwa kelas C diproleh informasi membentuk distribusi skew ke kanan atau ekor (tail) landa ke sumbu positif. Maka dapat dikatakan sebaran data nilai mahasiswa kelas C didominasi oleh nilai-nilai yang kecil. Sedangkan nilai mahasiwa kelas D secara kasat mata terlihat membentuk distribusi normal. Simetris mengalami puncak observasi di tengah. Sehingga dikatakan mahasiswa kelas D mempunyai sebaran nilai yang merata.

GRAFIK ANIMASI

Download datanya DISINI.

INPUT DATA

padi <- read.csv("E:\\BLOG\\MATERI\\MEMBUAT ANIMASI\\datapadi.csv", header = TRUE, sep = ";")
padi$Provinsi <- as.character(padi$Provinsi)
padi$Pulau <- as.character(padi$Pulau)
str(padi)
## 'data.frame':    363 obs. of  6 variables:
##  $ Provinsi     : chr  "Aceh" "Aceh" "Aceh" "Aceh" ...
##  $ Pulau        : chr  "Pulau Sumatera" "Pulau Sumatera" "Pulau Sumatera" "Pulau Sumatera" ...
##  $ Tahun        : int  2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 ...
##  $ Produktivitas: num  42.1 41.8 41.8 42.1 42.5 ...
##  $ Produksi     : int  1547499 1552078 1411650 1350748 1533369 1402287 1556858 1582393 1772962 1788738 ...
##  $ luas_lahan   : int  348232 346305 356649 315277 312803 323010 359751 313649 307556 308973 ...

Jadi pada materi kali ini kita akan membuat visualisasi dalam bentuk animasi produksi padi, luas lahan dan produktivitas tiap provinsi di indonesia sejak tahun 2003 sampai 2015. Seperti biasaa, langkah awal kita panggil dulu data nya ke direktori kerja.. pada command read.csv disesuuikan dengan lokasi file tempat teman2 menyimpan datanya ya. kalau sep = itu untuk pemisah atau separator yang digunakan. biasanya ada laptop yang menggunakan pemisah (;) ada yang (,). Kemudia perintah as.character itu untuk mengubah tipe datanya menjadi variabel. karena sebelumnya tipe data variabel provinsi dan pula itu factor.

SUBSET DATA

padi_sub <- padi[padi$Produksi > 8000000,]
padi_sub$tinggi <- ifelse(padi_sub$Produksi > 8000000, padi_sub$Provinsi, "")

Perintah diatas untuk memilah data yang ingin kita gunakan. karena nantinya hasil plot ingin diketahui provinsi mana yang memiliki total produksi lebih dari 8juta ton, maka harus kita identifikasi terlebih dahulu.

LOAD PACKAGE

library(ggplot2)
library(gganimate)
library(ggrepel)

options(scipen = 100)

mapping <- aes(x = Produksi , y = luas_lahan, 
               col = Pulau, size = Produktivitas,
               frame = Tahun) 

Perintah scipen = untuk mengatur format scientific pada R. jika kita pilih nilai minus (-) maka secara otomatis nanti hasil angka atau perhitungan kita akan keluar dengan format scientific. seperti 1e+03. Pun sebaliknya, jika kita atur dengan nilai positif maka hasilnya akan normal tanpa eksponensial. Perintah aes merupakan command dari package ggplot2berfungsi untuk mengatur variabel yang digunakan dan segala macam grafik yang ingin kita sisipkan. Pada kasus ini kita akan membuat sumbu x dengan variabel produksi, kemudian sumbu y dengan variabel luas lahan, kemudian identifikasi warna dengan kategori pulau, dan ukuran point berdasarkan produktivitas dan mengatur tiap perubahan grafik nya berdasarkan variabel tahun.

MEMBUAT GRAFIK ANIMASI

theme_set(theme_linedraw())
grafik <- ggplot(padi, mapping = mapping) +
  geom_point() +
  labs(title="Produksi & luas lahan", y="luas lahan (Ha)", x="Produksi (ton)", caption="Sumber data: Badan Pusat Statistik") +
  geom_label_repel(aes(label=tinggi), size=3, data=padi_sub) +
  theme(plot.title = element_text(size = 20, face = "bold", hjust = 0.5, color = "black", family="American Typewriter"), legend.position = "none")+
  scale_color_manual(name="Pulau", 
                       values = c("brown", "red", 
                                  "green", 
                                  "yellow",
                                  "blue", 
                                  "orange"))

Selanjtunya kita memasuki langkah mengkontruksi grafiknya. Perintah theme_set() untuk mengatur tema dari grafik. Ada beberapa macam pilihan. temen2 dapat mengskplor sendiri xD. Kemudian perintah labs() untuk mengatur label pada grafik. Sedangkan perintah geom_label_rapel() untuk menambahkan label pada data yang pada tahap sebelumnya telah kita pilah/subset. yaitu provinsi yang memiliki produksi padi lebih dari 8juta ton.

MEMANGGIL GRAFIK ANIMASI

gganimate(grafik, "output.gif")

Hasilnya dapat dilihat pada gambar diatas xD. sebenarnya masih bisa lebih dikembangkan lagi grafiknya dengan beberapa fitur yang ada di package ggplot2. namun pada materi ini cukup segitu dulu yak, pertemuan selanjutnya kita belajar bersama lagi. Temen2 dapat menyimpan hasil grafiknya dengan command `gganimate(namagrafik, “namafile.gif”).

Jadi berdasarkan gif diatas dapat diperoleh informasi, provinsi jawa barat, jawa tengah dan jawa timur memiliki jumlah produksi padi yang paling tinggi serta lahan sawah yang terluas sejak tahun 2003 hingga 2015. Sekian dan terimakasih, semoga bermanfaat!xD


Referensi :

[1] http://www.sthda.com/english/articles/16-r-packages/58-gganimate-create-animations-with-ggplot2/

[2] http://r-statistics.co/Complete-Ggplot2-Tutorial-Part2-Customizing-Theme-With-R-Code.html

[3] https://stats.idre.ucla.edu/r/modules/