1 Course Map

  1. Dive Deeper Into Data Wrangling & Exploration Tools
  2. Static Visualization Transformation/Interactive Plot
  3. Web Dashboard

2 Dive Deeper Into Data Wrangling & Exploration Tools

Pada course kali ini, kita akan menggunakan package tidyverse, package tersebut terdiri dari beberapa package. Dimana setiap package yang tedapat pada package tidyverse akan mempermudah kita dalam melakukan wrangling dan eksplorasi data.

# install.packages("tidyverse")
library(tidyverse)

Beberapa package umum yang terdapat di dalam tidyverse antara lain:

  • ggplot2
  • dplyr
  • tidyr
  • readr
  • purrr
  • tibble
  • stringr
  • forcats

Data transformasi dan data wrangling adalah suatu hal yang cukup krusial dalam melakukan persiapan data untuk dibuat suatu visualisasi atau analisis lanjutan. Salah satu package yang cukup useful dan akan kita gunakan saat ini adalah dplyr; yang juga masuk dalam environment yang besar tidyverse.

2.1 Read Data

Kali ini, kita akan menggunakan dataset dari #tidytuesday, yakni “Women in the workplace” dari biro statistik tenaga kerja dan biro sensus.

Pada data tersebut berisikan informasi mengenai statistik perbedaan jumlah pekerja dan penghasilan antara pekerja laki-laki dan perempuan pada sebuah posisi ataupun jabatan tertentu dari tahun 2013-2016.

# Please run the code down below
workers <- read.csv("data_input/jobs_gender.csv")

Deskripsi variabel:

  • year: Tahun
  • occupation: Posisi/pekerjaan tertentu
  • major_category: Departemen/divisi
  • minor_category: Sub-departemen/sub-divisi
  • total_workers: Total pekerja (full time, di atas 16 tahun)
  • workers_male: Total pekerja pria (full time, di atas 16 tahun)
  • workers_female: Total pekerja wanita (full time, di atas 16 tahun)
  • percent_female: Persentasi (proporsi) pekerja wanita untuk setiap posisi/pekerjaan tertentu
  • total_earnings: Median pendapatan setiap pekerja (full time, di atas 16 tahun)
  • total_earnings_male: Median pendapatan setiap pekerja pria (full time, di atas 16 tahun)
  • total_earnings_female: Median pendapatan setiap pekerja wanita (full time, di atas 16 tahun)
  • wage_percent_of_male: Rasio persentase pendapatan wanita dengan pria, bernilai NA untuk posisi/pekerjaan yang ukuran sampelnya kecil.

2.2 Data Wrangling & Exploratory dengan dplyr

dplyr adalah package khusus yang mempermudah kita dalam melakukan data wrangling ataupun eksplorasi data. Berikut beberapa tahapan yang akan kita lakukan dalam melakukan data wrangling ataupun eksplorasi data.

  • Inspeksi data
  • Seleksi kolom
  • Filter baris
  • Membuat atau mengubah kolom
  • Agregasi data
  • Mengurutkan baris

Official Documentation & Cheatsheet dplyr: https://dplyr.tidyverse.org/

2.2.1 Seleksi kolom

Tugas: Kita sebagai tim data diminta untuk mengambil data workers berdasarkan kolom year, occupation, dan total_workers.

Cara base:

# Please run the code down below
head(workers[,c("year", "occupation", "total_workers")])

Cara dplyr:

Fungsi yang akan digunakan adalah select()

Syntax: select(.data = object data, nama_kolom1, nama_kolom2)

# Please type your code here
head(select(.data = workers, year, occupation, total_workers))

Additional: Misal kita ingin membuang kolom major_category, dan wage_percent_of_male

# Please type your code here
head(select(.data = workers, -c(major_category, wage_percent_of_male)))

2.2.2 Filter baris

Tugas: Kita sebagai tim data diminta untuk mengambil data vpekerja yang ada pada tahun 2015 dan memiliki rata-rata pendapatan lebih dari 30,000.

Cara base:

# Please run the code down below
head(workers[workers$year %in% 2015 & workers$total_earnings > 30000, ])

Cara dplyr:

Fungsi yang akan digunakan adalah filter()

Syntax: filter(.data = object data, kondisi yang ingin dipenuhi)

Pada fungsi filter() : * , sama dengan notasi AND (&) * | sama dengan notasi OR (|)

# Please type your code here
head(filter(.data = workers, 
            year %in% 2015, total_earnings > 30000))

Additional Notes:

  • Keunggulan menggunakan filter() adalah mengurangi penulisan ulang nama object data dan penggunaan $.

2.2.3 Konsep Piping

Simbol %>% disebut sebagai piping, cara kerjanya adalah melanjutkan suatu proses ke proses lainnya secara sekuensial atau berurutan. Untuk lebih memahaminya, mari kita coba lihat perbandingan di bawah ini.

Sebagai contoh, kita memiliki data bunga iris yang memiliki 5 kolom sebagai berikut

# Please run the code down below
head(iris)

Deskripsi kolom:

  • Sepal.Length: Panjang ukuran daun
  • Sepal.Width: Lebar ukuran daun
  • Petal.Length: Panjang ukuran bunga
  • Petal.Width: Lebar ukuran bunga
  • Species: Jenis spesies (setosa, versicolor, virginica)

Dari data tersebut, mari kita coba ambil kolom Sepal.Length dan Species saja. Selain itu kita juga hanya akan mengambil data species dengan kategori setosa saja.

Hasil tanpa piping:

# Please type your code here
iris_setosa <- select(.data = iris, Sepal.Length, Species)
iris_setosa <- filter(.data = iris_setosa, Species == "setosa")

iris_setosa

Hasil dengan piping:

# Please type your code here
iris %>% 
  filter(Species == "setosa") %>% 
  select(Sepal.Length, Species)

2.2.4 Inspeksi data

Salah satu langkah yang tidak boleh tertinggal ketika melakukan persiapan data adalah melihat struktur data kita untuk mengetahui tipe data apa saja yang belum sesuai.

Cara base:

# Please run the code down below
str(workers)
#> 'data.frame':    2088 obs. of  12 variables:
#>  $ year                 : int  2013 2013 2013 2013 2013 2013 2013 2013 2013 2013 ...
#>  $ occupation           : chr  "Chief executives" "General and operations managers" "Legislators" "Advertising and promotions managers" ...
#>  $ major_category       : chr  "Management, Business, and Financial" "Management, Business, and Financial" "Management, Business, and Financial" "Management, Business, and Financial" ...
#>  $ minor_category       : chr  "Management" "Management" "Management" "Management" ...
#>  $ total_workers        : int  1024259 977284 14815 43015 754514 44198 109703 489048 990611 14656 ...
#>  $ workers_male         : int  782400 681627 8375 17775 440078 16141 72873 354369 460842 3387 ...
#>  $ workers_female       : int  241859 295657 6440 25240 314436 28057 36830 134679 529769 11269 ...
#>  $ percent_female       : num  23.6 30.3 43.5 58.7 41.7 63.5 33.6 27.5 53.5 76.9 ...
#>  $ total_earnings       : int  120254 73557 67155 61371 78455 74114 62187 99167 70456 71927 ...
#>  $ total_earnings_male  : int  126142 81041 71530 75190 91998 90071 66579 101318 90278 97552 ...
#>  $ total_earnings_female: int  95921 60759 65325 55860 65040 66052 55079 90940 57406 68207 ...
#>  $ wage_percent_of_male : num  76 75 91.3 74.3 70.7 ...

Cara dplyr:

Fungsi yang akan digunakan adalah glimpse()

# Please type your code here
glimpse(workers)
#> Rows: 2,088
#> Columns: 12
#> $ year                  <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, …
#> $ occupation            <chr> "Chief executives", "General and operations mana…
#> $ major_category        <chr> "Management, Business, and Financial", "Manageme…
#> $ minor_category        <chr> "Management", "Management", "Management", "Manag…
#> $ total_workers         <int> 1024259, 977284, 14815, 43015, 754514, 44198, 10…
#> $ workers_male          <int> 782400, 681627, 8375, 17775, 440078, 16141, 7287…
#> $ workers_female        <int> 241859, 295657, 6440, 25240, 314436, 28057, 3683…
#> $ percent_female        <dbl> 23.6, 30.3, 43.5, 58.7, 41.7, 63.5, 33.6, 27.5, …
#> $ total_earnings        <int> 120254, 73557, 67155, 61371, 78455, 74114, 62187…
#> $ total_earnings_male   <int> 126142, 81041, 71530, 75190, 91998, 90071, 66579…
#> $ total_earnings_female <int> 95921, 60759, 65325, 55860, 65040, 66052, 55079,…
#> $ wage_percent_of_male  <dbl> 76.04208, 74.97316, 91.32532, 74.29179, 70.69719…

Kolom apa saja yang belum sesuai dari hasil inspeksi datanya?

  • year
  • occupation
  • major_category
  • minor_category

2.2.5 Modifikasi tipe data & kolom

Dalam melakukan data manipulation, kita bisa melakukan manipulasi terhadap class dari kolom atau menambahkan kolom baru pada data.

2.2.5.1 Modifikasti tipe data

Dari beberapa kolom yang tipe datanya belum sesuai mari kita coba ubah terlebih dahulu menjadi tipe yang lebih sesuai

Cara base:

# Please run the code down below
workers$occupation <- as.factor(workers$occupation)

Cara dplyr:

Fungsi yang akan digunakan adalah mutate()

Syntax: mutate(nama_kolom = as.factor(nama_kolom))

# Please type your code here
workers_clean <- workers %>% 
  mutate(year = as.factor(year)) %>% 
  mutate_if(is.character, as.factor)
workers_clean %>% 
  glimpse()
#> Rows: 2,088
#> Columns: 12
#> $ year                  <fct> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, …
#> $ occupation            <fct> "Chief executives", "General and operations mana…
#> $ major_category        <fct> "Management, Business, and Financial", "Manageme…
#> $ minor_category        <fct> "Management", "Management", "Management", "Manag…
#> $ total_workers         <int> 1024259, 977284, 14815, 43015, 754514, 44198, 10…
#> $ workers_male          <int> 782400, 681627, 8375, 17775, 440078, 16141, 7287…
#> $ workers_female        <int> 241859, 295657, 6440, 25240, 314436, 28057, 3683…
#> $ percent_female        <dbl> 23.6, 30.3, 43.5, 58.7, 41.7, 63.5, 33.6, 27.5, …
#> $ total_earnings        <int> 120254, 73557, 67155, 61371, 78455, 74114, 62187…
#> $ total_earnings_male   <int> 126142, 81041, 71530, 75190, 91998, 90071, 66579…
#> $ total_earnings_female <int> 95921, 60759, 65325, 55860, 65040, 66052, 55079,…
#> $ wage_percent_of_male  <dbl> 76.04208, 74.97316, 91.32532, 74.29179, 70.69719…

Additional Notes:

  • Untuk menyimpan perubahan jangan lupa di assign ke dalam sebuah object.
  • Jangan menyimpan hasil cleansing data pada nama objek yang sama supaya apabila ingin melakukan perubahan yang lainnya, maka tidak perlu mengulang dari import data.

2.2.5.2 Modifikasti kolom

Kita akan mencoba menambahkan kolom baru, yaitu:

  • earnings_different: selisih pendapatan antara pegawai pria dan peremuan

Cara base:

# Please run the code down below
workers$earnings_different <- workers$total_earnings_male - workers$total_earnings_female

Cara dplyr:**

Fungsi yang akan digunakan adalah mutate()

Syntax: mutate(nama_kolom_baru = kondisi_pembuatan_kolom)

# Please type your code here
workers_clean <- workers_clean %>% 
  mutate(earnings_different = total_earnings_male - total_earnings_female)

2.2.6 Agregasi Data

Tugas: Ternyata pekerjaan kita masih belum selesai, kita diminta untuk menghitung rata-rata pendapatan berdasarkan masing-masing divisinya.

Cara base:

# Please run the code down below
mean_earn <- aggregate(x = total_earnings ~ major_category, 
          data = workers_clean, 
          FUN = mean)

mean_earn

Cara dplyr:

Pada dplyr, kita dapat melakukan aggregasi data menggunakan urutan fungsi berikut:

  • group_by(): melakukan pengelompokkan berdasarkan kolom tertentu, sehingga proses apapun setelahnya dilakukan berdasarkan pengelompokkan tersebut.
  • summarise():

Syntax: group_by(nama_kolom1, nama_kolom2) %>% summarise(nama_kolom_baru = mean(nama_kolom)

# Please type your code here
workers_clean %>% 
  group_by(major_category) %>% 
  summarise(mean_earning = mean(total_earnings))

2.2.7 Mengurutkan baris

Tugas: Agar hasil agregasi untuk rata-rata views dari setiap trending video.

Cara base:

# Please run the code down below
mean_earn[order(mean_earn$total_earnings, decreasing = T),]

Cara dplyr:

Fungsi yang akan digunakan adalah arrange()

Syntax: arrange(nama_kolom)

# Please type your code here
workers_clean %>% 
  group_by(major_category) %>% 
  summarise(mean_earning = mean(total_earnings)) %>% 
  arrange(-mean_earning)

###️ Dive Deeper

Background: Kevin merupakan salahs satu tim dari biro statistik tenaga kerja, beliau meminta tolong kita untuk melakukan analisa mengenai beberapa hal dari data yang kita miliki, agar nantinya hasil dari analisisnya bisa kita buat sebagai plot interaktif dan dicantumkan ke Dashboard.

  1. Berapakah rata-rata perbedaan pendapatan (earning_different) yang diperoleh oleh pegawai laki-laki dengan perempuan untuk masing-masing sub-divisi (minor_category) di tahun 2016?
case1 <- workers_clean %>%  
  filter(year == 2016) %>% 
  group_by(minor_category) %>% 
  summarise(mean_gap_earn = mean(earnings_different)) %>% 
  ungroup() %>% 
  arrange(-mean_gap_earn) %>% 
  drop_na()

case1
  1. Sub-divisi apa sajakah yang didominasi oleh pegawai perempuan dibandingkan dengan pekerja laki-laki? Dan berapakan ada berapah jumlah kemunculannya, pada tahun 2016?
workers_agg2 <- workers_clean %>% 
  filter(workers_female > workers_male, year == 2016) %>% 
  group_by(minor_category) %>% 
  summarise(total = n()) %>% 
  ungroup() %>% 
  arrange(-total)

workers_agg2

3 Static Visualization Transformation/Interactive Plot

Seiring bertambahnya data dalam kompleksitas dan ukuran, sering kali tim analis diberi tugas yang sulit untuk menyeimbangkan storytelling dengan hasil visualisasinya. Tim Analis juga ditugaskan untuk menemukan keseimbangan yang baik antara cakupan dan detail di bawah batasan grafik dan plot statis.

Harapannya dengan melakukan transformasi dari plot yang statis menjadi plot interaktif, kita sebagai tim analis dapat menyampaikan informasi yang lebih informatif dan menarik.

3.1 Interactive Plot dengan plotly

Packages plotly adalah salah satu package yang sangat dipuji dalam komunitas data science karena kapabilitas dan fleksibilitasnya untuk membantu kita dalam membuat visual interaktif dari objek ggplot.

Official Documentation plotly: https://plotly.com/r/

# install.packages("plotly")
library(plotly)

Tahapan pembuatan interactive plot menggunakan plotly:

  1. Formulasikan business question
  2. Persiapan data
  3. visualisasi statis dengan ggplot()
  4. Mengubah objek ggplot menjadi plotly dengan ggplotly()

3.1.1 Plot 1

BQ: Berapakah rata-rata perbedaan pendapatan (earning_different) yang diperoleh oleh pegawai laki-laki dengan perempuan untuk masing-masing sub-divisi (minor_category) di tahun 2016?

  • Persiapan data
# Please type your code here
case1 <- workers_clean %>%  
  filter(year == 2016) %>% 
  group_by(minor_category) %>% 
  summarise(mean_gap_earn = mean(earnings_different)) %>% 
  arrange(-mean_gap_earn) %>% 
  drop_na()

case1
  • Visualisasi Statis
library(scales)

plot1 <- ggplot(data = case1, aes(x = mean_gap_earn,
                         y = reorder(minor_category, mean_gap_earn)))+
  geom_col(mapping = aes(fill = mean_gap_earn))+
  scale_x_continuous(labels = comma) + # Memberikan koma per 3 digit pada sumbu x
  scale_fill_gradient(low = "orange", high = "red") +
  labs(y = NULL, x = "Rata-rata pendapatan", 
       title = "Rata-rata Gap Pendapatan Laki-laki dan Perempuan")+
  theme_minimal() +
  theme(legend.position = "none") 
  
plot1

  • Mengubah objek ggplot menjadi interaktif

Fungsi yang akan digunakan ggplotly()

# Please type your code here
ggplotly(p = plot1)

3.1.1.1 Tooltip

Tooltip adalah informasi atau label yang ditampilkan ketika user meng-hover plot.

# install.packages("glue")
library(glue)
# contoh penggunaan fungsi glue dari library glue
nama <- c("Handoyo", "Nabiila", "Kevin", "Lita", "Victor")
glue("Nama Instructor: {nama}")
#> Nama Instructor: Handoyo
#> Nama Instructor: Nabiila
#> Nama Instructor: Kevin
#> Nama Instructor: Lita
#> Nama Instructor: Victor

Tahapan dalam menambahkan tooltip:

  1. Pada tahapan persiapan data, tambahkan kolom berisi informasi tulisan pada tooltip. Fungsi glue() digunakan untuk menampilkan nilai pada kolom.
# Please type your code here

case1 <- case1 %>% 
  mutate(text = glue("Rata-rata pendapatan: {round(mean_gap_earn, 2)}
                     Sub-Divisi: {minor_category}"))
head(case1)
  1. Membuat ulang visualisasi dengan menambahkan parameter text pada aes()
# Please type your code here
plot1 <- ggplot(data = case1, aes(x = mean_gap_earn,
                         y = reorder(minor_category, mean_gap_earn),
                         text = text))+
  geom_col(mapping = aes(fill = mean_gap_earn))+
  scale_x_continuous(labels = dollar_format(prefix = "$")) + # Memberikan koma per 3 digit pada sumbu x
  scale_fill_gradient(low = "orange", high = "red") +
  labs(y = NULL, x = "Rata-rata pendapatan", 
       title = "Rata-rata Gap Pendapatan Laki-laki dan Perempuan")+
  theme_minimal() +
  theme(legend.position = "none") 
  1. Menambahkan parameter tooltip = "text" pada ggplotly()
# Please type your code here

ggplotly(plot1, tooltip = "text")

3.1.2 Plot 2

BQ: Sub-divisi apa sajakah yang didominasi oleh pegawai perempuan dibandingkan dengan pekerja laki-laki? Dan berapakan ada berapah jumlah kemunculannya?

  • Pada plot kedua ini, kita akan langsung menambahkan fungsi glue() pada parameter text = di fungsi aes() ketika kita mempersiapkan ggplot().
plot2 <- ggplot(data=workers_agg2, aes(x=total,
                                     y=reorder(minor_category,total),
                                     text = glue("Number of Occupations : {total}"))) +
  geom_point(col="red", size=3) + 
  # geom_col(width = 0.04)+
  geom_segment(aes(x = 0, xend=total, y=minor_category,
                   yend=reorder(minor_category, total)))+
  labs(x=NULL, y=NULL, title = "Jumlah Posisi yang Didominasi Perempuan") +
  theme_minimal()

ggplotly(plot2, tooltip = "text")

3.2 Plot 3

BQ: Bagaimana distribusi pendapatan pegawai berdasarkan jenis kelaminnya pada tahun 2016?

case3 <- workers_clean %>% 
        filter(year == 2016) %>% 
        select(total_earnings_male, total_earnings_female) %>% 
        pivot_longer(cols = c(total_earnings_male, total_earnings_female))
case3 %>% head(3)
plot3 <- ggplot(data = case3, 
                mapping = aes(x = value)) +
  geom_density(aes(fill = name), alpha = 0.7) +
  labs(title = "Earnings Distributions", 
       x = NULL,
       y = "Density",
       fill = "Gender") +
  scale_fill_brewer(palette = "Set1")+
  theme_minimal()

ggplotly(plot3, tooltip = "x")

4 Web Dashboard

4.1 Flexdashboard

Flex Dashboard adalah paket R yang mudah membuat dasbor fleksibel, menarik, dan interaktif”. Pembuatan dan penyesuaian dasbor dilakukan menggunakan R Markdown dengan format output flexdashboard::flex_dashboard.

# install.packages("flexdashboard")
library(flexdashboard)

Langkah membuat file Rmd dengan template flexdashboard:

  1. Pilih Menu File > New File > R Markdown
  2. Pada bagian “From Template”, pilih “Flex Dashboard”
  3. Klik tombol “OK”
  4. Simpan file Rmd dan beri nama file (bisa dengan shortcut CTRL + S)

4.2 Shiny

Shiny adalah packages dari RStudio, yang menyediakan framework aplikasi web untuk membuat aplikasi web interaktif (visualisasi) yang disebut “Shiny apps”. Kemudahan bekerja dengan Shiny telah mempopulerkannya di antara pengguna R. Aplikasi web ini menampilkan objek R dengan cantik (seperti plot, tabel, dll.) dan juga dapat di-deploy untuk memungkinkan diakses oleh siapa saja.

Shiny menyediakan widget yang memungkinkan untuk membangun aplikasi yang elegan dengan sedikit usaha.

Struktur aplikasi shiny dasar:

knitr::include_graphics(path = "assets/shiny architecture.png")

  • global.R: Untuk menyiapkan lingkungan aplikasi, misalnya, library, impor data dan persiapan data.
  • ui.R: User Interface (UI) untuk menampilkan input dan output.
  • server.R: Untuk memproses input dari user dan mengubahnya menjadi output.
# install.packages("shinydashboard")
library(shinydashboard)

Referensi: