1 About The Dataframe

Salahs satu data yang akan kita gunakan untuk mendalami Data Visualization adalah sebuah dataframe yang bernama Youtube’s US Trending Videos.

Contoh trending video di Youtube:

# Please run code down below
knitr::include_graphics("assets/trending_2022.png")

1.1 Data Import / Read Data

# Please run code down below
vids <- read.csv("data_input/USvideos_2023.csv")
head(vids)

Penjelasan mengenai 12 kolom dalam dataframe:

  • trending_date: tanggal trending (format: YY.DD.MM)
  • title: judul video
  • channel_title: nama channel Youtube
  • category_id: kategori video
  • publish_time: tanggal upload video (format: YYYY-MM-DD-HH-MM-SS)
  • views: jumlah views dalam video tersebut
  • likes: jumlah likes dalam video tersebut
  • dislikes: jumlah dislikes dalam video tersebut
  • comment_count jumlah komentar
  • comment_disabled: apakah kolom komentar tidak diaktifkan
  • rating_disabled: apakah rating video tidak diaktifkan
  • video_error_or_removed: apakah video dihapus

Setelah melakukan import dataframe yang ingin digunakan jangan lupa untuk melakukan inspeksi tipe data, untuk memastikan tipe data sudah sesuai.

# Inspect Data Type 

Apa saja kolom yang tipe datanya belum sesuai?

Kenapa melakukan inspeksi tipe data itu penting sebelum melanjutkan ke tahap selanjutnya? Untuk memastikan bahwa semua tipe data yang ada pada dataframe tersebut sudah sesuai dan bisa diolah lebih lanjut.

1.2 Data Wrangling

Data Wrangling merupakan sebuah tahapan persiapan ataupun pembersihan data, agar hasil dari visualisasi yang ditampilkan bisa menunjukan data yang bersih (tidak salah intepretasi) dan menampilkan beberapa aspek yang kita butuhkan (walaupun belom tersedia pada data mentah).

1.2.1 Manipulasi data waktu menggunakan library lubridate

Penggunaan lubridate secara singkat dapat dilihat di cheatsheet

#install.packages("lubridate")
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
  • Kolom trending_date

Before:

str(vids$trending_date)
##  chr [1:72389] "23.01.01" "23.01.01" "23.01.01" "23.01.01" "23.01.01" ...

After:

# Please type your code
# Format date dari kolom trending_date = Year-Day-Month
str(ymd(vids$trending_date))
## Warning: 44200 failed to parse.
##  Date[1:72389], format: "2023-01-01" "2023-01-01" "2023-01-01" "2023-01-01" "2023-01-01" ...
vids$trending_date <- ymd(vids$trending_date)
## Warning: 44200 failed to parse.
  • Kolom publish_time

Before:

str(vids$publish_time)
##  chr [1:72389] "2023-01-01T05:12:55Z" "2022-12-31T20:00:04Z" ...

After:

# Please type your code
# Format date dari kolom publish_date = Year-Month-Day-Hour-Month-Day
str(ymd_hms(vids$publish_time))
##  POSIXct[1:72389], format: "2023-01-01 05:12:55" "2022-12-31 20:00:04" "2023-01-01 01:11:58" ...
vids$publish_time <- ymd_hms(vids$publish_time)

Discalimer: POSIXct/POSIXt adalah tipe data untuk data yang memiliki tanggal & waktu

  • Additional Parameter

Kita bisa merubah timezone (zona waktu) List time zone: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

Kita ubah timezone menjadi Jakarta

# Please run code down below
head(ymd_hms(vids$publish_time, tz = "Asia/Jakarta"))
## Warning: 13 failed to parse.
## [1] "2023-01-01 05:12:55 WIB" "2022-12-31 20:00:04 WIB"
## [3] "2023-01-01 01:11:58 WIB" "2022-12-31 14:59:56 WIB"
## [5] "2023-01-01 05:21:44 WIB" "2022-12-31 20:51:09 WIB"

Kita ubah timezone menjadi New_York

# Please run code down below
head(ymd_hms(vids$publish_time, tz = "America/New_York"))
## Warning: 13 failed to parse.
## [1] "2023-01-01 05:12:55 EST" "2022-12-31 20:00:04 EST"
## [3] "2023-01-01 01:11:58 EST" "2022-12-31 14:59:56 EST"
## [5] "2023-01-01 05:21:44 EST" "2022-12-31 20:51:09 EST"

Discalimer: Jika ada data waktu, kita bisa mengatur zona waktunya dengan menambahkan parameter tz =

1.2.2 Ekstraksi data waktu menggunakan library lubridate

Library lubridate tidak hanya terbatas untuk melakukan pengubahan tipe data, melainkan bisa juga dimanfaatkan untuk mengambil informasi/ekstraksi dari kolom data yang sudah diubah tipe datanya menjadi date-time (POSIXct/POSIXt).

Sebagai contoh prosesnya, mari kita coba untuk mengambil informasi nama hari dari kolom trending_date

# Please type your code
head(wday(x = vids$trending_date, 
     label = T, 
     abbr = T))
## [1] Sun Sun Sun Sun Sun Sun
## Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat

Selain dari informasi tanggal, ekstraksi juga dapat dilakukan pada informasi waktu. Berikut contoh mengambil informasi menit dari kolom publish_time

# Please type your code
head(minute(vids$publish_time))
## [1] 12  0 11 59 21 51

DIVE DEEPER

  1. Buat kolom baru berisi hari publish video dan jam publish video untuk vids. Beri nama publish_day dan publish_hour dari kolom publish_time
  • publish_day

Hint: label = T, abbr = F

# Please type your code
# vids$publish_day <- 
vids$publish_day <- wday(vids$publish_time, label = T, abbr = F)
  • publish_hour
# Please type your code
# vids$publish_hour <- 
vids$publish_hour <- hour(vids$publish_time)
  1. Buat kolom berisi berapa lama waktu untuk trending? Beri nama time_to_trend

Hint:

  • buat kolom publish_date yang isinya hanya tanggal (YYY-MM-DD) dari kolom publish_time
  • mengurangkan kolom trending_date dengan publish_date kemudian ubah menjadi numeric
# Please type your code
# vids$publish_date <-
vids$publish_date <-  date(vids$publish_time)
# Please type your code
# vids$time_to_trend <-
vids$time_to_trend <-  vids$trending_date - vids$publish_date

1.2.3 Membuat kategori jam untuk kolom publish_hour

# Please run the code down below
head(vids$publish_hour)
## [1]  5 20  1 14  5 20

Fungsional yang akan kita gunakan pada kasus ini adalah case_when() dari library dplyr, fungsi tersebut bisa dibilang equivalent dengan konsep if-else, dimana kita akan membuat beberapa kondisi berdasarkan data yang ada untuk menghasilkan suatu hal yang baru.

Kita akan mengkategorikan publish_hour menjadi 3 kategori:

  • 12am to 8am
  • 8am to 3pm
  • 3pm to 12am
#install.packages("dplyr")
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

Berikut adalah contoh syntax dari fungsi `case_when():

case_when(
nama_df$nama_kolom {logical_operator} kondisi_1 ~ "expected_output_1",
nama_df$nama_kolom {logical_operator} kondisi_2 ~ "expected_output_2",
)
# Please run the code down below
vids$publish_when <- 
case_when(vids$publish_time <= 8 ~ "12am to 8am",
          vids$publish_time > 8 & vids$publish_time < 16 ~ "8am to 3pm",
          vids$publish_time >= 16 ~ "3pm to 12am")

1.2.4 Merubah category_id

Pada tahapan ini kita akan melakukan transformasi pada kolom category_id dari angka yang tidak bermakna menjadi nama kategori yang lebih intuitif.

# Please run the code down belom
vids[ , c("channel_title", "category_id")]
# Please run the code down below
vids$category_id <- 
case_when(vids$category_id == "1"  ~ "Film and Animation",
          vids$category_id == "2"  ~ "Autos and Vehicles", 
          vids$category_id == "10" ~ "Music", 
          vids$category_id == "15" ~ "Pets and Animals", 
          vids$category_id == "17" ~ "Sports",
          vids$category_id == "19" ~ "Travel and Events", 
          vids$category_id == "20" ~ "Gaming", 
          vids$category_id == "22" ~ "People and Blogs", 
          vids$category_id == "23" ~ "Comedy",
          vids$category_id == "24" ~ "Entertainment", 
          vids$category_id == "25" ~ "News and Politics",
          vids$category_id == "26" ~ "Howto and Style", 
          vids$category_id == "27" ~ "Education",
          vids$category_id == "28" ~ "Science and Technology", 
          vids$category_id == "29" ~ "Nonprofit and Activism",
          vids$category_id == "43" ~ "Shows")

1.2.5 Mengambil judul video yang unik

Dalam data vids terdapat redudansi data yaitu terdapat video yang muncul beberapa kali karena trending lebih dari 1 hari.

# Please run the code down below
length(vids$title)
## [1] 72389
length(unique(vids$title))
## [1] 12595

Untuk analisis lanjutan, kita hanya akan menggunakan data video saat video tersebut pertama kali trending demi mengurangi redudansi data. Untuk itu kita dapat menggunakan distinct(). Untuk lebih memahami fungsi distinct() kita akan menggunakan contoh di bawah terlebih dahulu.

# Please run the code down below
df <- data.frame(nama = c("Victor", "Victor", "Tomy", "Kevin", "Kevin", "Tomy"),
           nilai = c(70, 95, 85, 80, 70, 90))
df
# Please run the code down below
distinct(.data = df, # data frame
         nama, # nama kolom yang ingin dicek
         .keep_all = T) # untuk menampilkan keseluruhan kolom

Mari kita kurangi redudasi data yang terdapat di dataframe vids dan simpan dalam object baru bernama vids.unik

# Please type your code down below
vids.unik <- distinct(.data = vids,
                      title,
                      .keep_all = T)
length(vids.unik$title)
## [1] 12595

2 Basic plotting in R

Exploratory Data Analysis Bertujuan untuk mendapat informasi dari data (explorasi). EDA biasa dilakukan menggunakan base plot.

Fungsi yang akan digunakan untuk melakukan base plot adalah plot(), jenis plot yang dihasilkan berubah sesuai tipe data yang dimasukkan, jika:

  • 1 variabel, x kategori: bar chart
  • 1 variabel, x numerik: histogram plot
    • Opsional function: hist()
  • 2 variabel, x dan y adalah numerik: scatter plot
  • 2 variabel, x kategori, y numerik: boxplot
    • Opsional function: boxplot()
  • 2 variabel, x date, y numerik: line plot
    • Additional parameter: type = “l”

2.1 Histogram

Business case: Klien tersebut sangat tertarik untuk membuat konten dengan kategori Autos and Vehicles, Gaming dan Travel and Events. Klien tersebut ingin mendapatkan gambaran secara garis besar berapakah distribusi like ratio yang bisa didapatkan dari ketiga kategori tersebut?

Hint:

  • Like ratio dapat dihitung dengan membagi like dengan view
  • Melakukan conditional subseting

Step 1: Menghitung like ratio lalu simpan ke objek bernama like_ratio

# Please type your code down below
vids.unik$like_ratio <- vids.unik$likes / vids.unik$views
head(vids.unik$like_ratio)
## [1] 0.012747092 0.065854814 0.009816257 0.052809392 0.008272446 0.008730818

Step 2: Melakukan conditional subseting untuk 3 unique value lalu simpan ke objek baru bernama vids.agt

vids.agt <- vids.unik[vids.unik$category_id %in% c("Autos and Vehicles", "Gaming", "Travel and Events"), ]

Step 3: Visualisasi

Ketika kita ingin membuat histogram plot, kita tidak menggunakan fungsi plot(), melainkan kita akan menggunakan fungsi hist()

# Please type your code down below
hist(vids.agt$like_ratio, breaks = 5)

Insight:

2.2 Scatter plot

Business case: Pertanyaan terakhir yang diajukan oleh klien kita adalah beliau juga ingin megetahui hubungan likes dan comment dari video dengan ketiga category tersebut. Agar dapat menentukan content manakah yang tepat untuk di publish sehingga memperoleh likes ratio yang banyak dan comment ratio yang banyak?

Hint: Rasio didapatkan dari membagi comment dengan jumlah view per judul video

Step 1: Menghitung comment ratio lalu simpan ke objek bernama comment_ratio

# Please type your code down below
vids.agt$comment_ratio <- vids.agt$comment_count / vids.agt$views
head(vids.agt$comment_ratio)
## [1] 0.003571713 0.002453289 0.002661927 0.001177459 0.004594201 0.006757668

Step 2: Melakukan visualisasi

# Please type your code down below
plot(x = vids.agt$like_ratio,
     y = vids.agt$comment_ratio,
     col = as.factor(vids.agt$category_id),
     pch = 16)

Plot sudah terbentuk tapi kita kekurangan informasi kita tidak tahu titik mana dengan kategori Autos and Vehicles, Gaming atau Travel and Events Kita juga ingin menambahkan garis tren hubungan antara 2 variabel

Step 3: Menambahkan Legend

Untuk memberikan lagenda pada scatter plot kita bisa menambahkan fungsi legend(), pada fungsi tersebut nantinya kita bisa mengisi beberapa parameter + x = mengatur posisi legend + legend = unique value dari kolom yang ingin ditampilkan + fill = untuk memberikan warna, sesuai dengan jumlah unique value dari kolom yang ingin ditampilkan

# Please type your code down below
plot(x = vids.agt$like_ratio,
     y = vids.agt$comment_ratio,
     col = as.factor(vids.agt$category_id),
     pch = 16)
legend(x = "right", #bottom, top, left (tapi cuma bisa di dalam plotnya)
       legend = levels(as.factor(vids.agt$category_id)),
       fill = 1:3)

Step 4: Menambahkan garis tren

Untuk memberikan garis yang menunjukan apakah ada tren positif ataupun negatif kita bisa menambahkan fungsi abline() + Pada fungsi tersebut nantinya bisa di isi dengan fungsi lm() yang akan membuat garis linear berdasarkan perhitungan linear model, dengan mengisi beberapa parameter berikut ini - formula = parameter ini bisa diisi dengan numerik sumbu y ~ numerik sumbu x - data = dataframe yang digunakan

# Please type your code down below
plot(x = vids.agt$like_ratio,
     y = vids.agt$comment_ratio,
     col = as.factor(vids.agt$category_id),
     pch = 16)
legend(x = "right", #botoom, top, left (tapi cuma bisa di dalam plotnya)
       legend = levels(as.factor(vids.agt$category_id)),
       fill = 1:3)
abline(lm(formula = comment_ratio ~ like_ratio,
          data = vids.agt))

Insight:

  • Kita bisa menyarankan untuk membuat konten video dengan category Autos and Vehicles, karena like ratio cukup bagus dan dislikes rationya relatif rendah.

2.3 Line plot

Business Case: Sebagai seorang Data Analyst kita ingin menganalisa perkembangan trending dari hari ke harinya

Step 1: Membuat objek dengan yang berisikan jumlah trending video dari hari ke harinya lalu simpan ke dalam sebuah objek dengan nama trending

Hint:

  • table() adalah fungsi yang dapat dimanfaatkan untuk menghitung berapa kali chaneel tersebut menjadi trending
  • as.data.frame() adalah fungsi yang dapat dimanfaatkan untuk mengubah list menjadi dataframe
# Please type your code down below
trending <- as.data.frame(table(vids.unik$trending_date))
trending

Step 2: Mengubah tipe data untuk kolom yang berisikan informasi tanggal menjadi date

# Please type your code down below
trending$Var1 <- ymd(trending$Var1)
class(trending$Var1)
## [1] "Date"

Step 3: Melakukan visualisasi

# Please type your code down below
plot(x = trending$Var1, y = trending$Freq, type = "l")

Insight:

3 Grammar of Graphics with ggplot2

Base plot amat berguna untuk melakukan eksplorasi data di awal dimana codingannya cukup sederhana. Ia dapat menyampaikan informasi mengenai data (distribusi/pola data) dan hubungan antar data secara cepat.

Sistem grammar yang digunakan pada base plot adalah membuat fungsi secara berurutan dan harus dijalankan bersamaan sehingga tidak begitu fleksibel dalam kostumisasi plot.

3.1 What is ggplot

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

Apa itu ggplot2? ggplot2 adalah sebuah libary yang akan menyediakan sebuah kanvas kosong yang dapat digunakan untuk membuat visualisasi. Sistem pembuatannya akan berdasarkan grammar formula of visualization dan layer by layer. Kedua sistem pembuatannya sangat bisa untuk dikutomisasi sehingga plot yang disajikan nantinya sangat cocok jika ingin ditampilkan kepada audiens.

Grammar formula of ggplot2 ggplot(data = ..., mapping = aes(x=..., y=...)) + geom_... + ...

ggplot(data = , mapping = aes(x=, y=))

Untuk lebih kenal dengan library ggplot2 mari kita coba melakukan visualisasi!

Business case: Kita sebagai data analyst ingin mencari tahu tentang likeability (like_ratio) & enggagement (comments_ratio) yang tinggi pada categry Autos and Vehicles, Gaming dan Travel and Events, manakah kategori yang paling baik untuk dibuatkan konten?

Step 1: Buatlah kolom baru yang berisikan ratio comment dengan views

Hint:

  • Gunakan objek vids.agt
  • Buatlah object baru bernama comment_ratio yang berisikan hasil bagi kolom comment_count dengan kolom views
# Please Type Your Code Down Below
head(vids.agt$comment_ratio)
## [1] 0.003571713 0.002453289 0.002661927 0.001177459 0.004594201 0.006757668

Step 2: Masukan parameter yang diperlukan untuk fungsi ggplot()

Parameter pada fungsi ggplot(),

  • data = dataframe yang ingin digunakan
  • mapping = parameter ini akan di isi dengan Aesthetic / aes(), aes() adalah fungsi yang bisa diisi dengan elemen-elemen yang penting dalam grafik, meliputi sumbu x, sumbu y.
# Please Type Your Code Down Below
# Main layer
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio))

Step 3: Menambahkan layer

Layer 1 - Boxplot

Untuk menambahkan layer pada main layer, kita bisa menggunakan simbol +

# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio)) +
  geom_boxplot() 

Layer 2- scatterplot

geom_point

# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio)) +
  geom_boxplot() +
  geom_point()

geom_jitter

# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio)) +
  geom_boxplot() +
  geom_jitter()

Notes:

  • geom_jitter: scatterplot dengan titik yang random bergeser ke kiri/kanan, agar tidak tumpang tindih

Step 4: Menambahkan parameter Aesthetic untuk fungsi geom

# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio)) +
  geom_boxplot() +
  geom_jitter(mapping = aes(size = comment_ratio))

Step 5: Menambahkan warna pada plot

Untuk memberikan warna pada plot kita, kita bisa memanfaatkan parameter color atau fill pada fungsi aes()

  • Menggunakan parameter fill
# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio, fill = category_id)) +
  geom_boxplot() +
  geom_jitter(mapping = aes(size = comment_ratio))

  • Menggunakan parameter color
# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio, color = category_id)) +
  geom_boxplot() +
  geom_jitter(mapping = aes(size = comment_ratio)) 

  • Pengaruh penempatan parameter pada fungsi aes()

Ditempatkan pada fungsi ggplot()

# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio, color = category_id)) +
  geom_boxplot() +
  geom_jitter(mapping = aes(size = comment_ratio)) 

Ditempatkan pada fungsi salah satu geom_

# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio)) +
  geom_boxplot(mapping = aes(color = category_id)) +
  geom_jitter(mapping = aes(size = comment_ratio)) 

ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio, fill = category_id)) +
  geom_boxplot(mapping = aes(color = category_id)) +
  geom_jitter(mapping = aes(size = comment_ratio)) 

Step 6: Menambahkan keterangan title, subtitle, legends, dan label sumbu x dan y dengan menggunakan fungsi labs()

# Please Type Your Code Down Below
ggplot(data = vids.agt,
       mapping = aes(x = category_id, y = like_ratio)) +
  geom_boxplot(mapping = aes(color = category_id)) +
  geom_jitter(mapping = aes(size = comment_ratio)) +
  labs(title = "Like & Comment Ratio",
       subtitle = "Category: Autos and Vehicles, Gaming, Travel and Events",
       x = "category",
       y = "Like Ratio",
       size = "Comment Ratio",
       color = "Category") +
  theme_minimal()

library(ggthemes) # untuk menambahkan library yang lainnya

Insight: