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
readr
Biasanya kita menggunakan fungsi read.csv()
untuk
membaca data. Kali ini mari kita coba menggunakan fungsi
read_csv()
dari library readr
untuk membaca
data YouTube Trending 2017, All Unique Videos.
Perbedaan menggunakan read_csv()
dibandingkan
read.csv()
:
read_csv()
membaca CSV ke dalam bentuk tibble (modern
dataframe), sering digunakan untuk menghandle data yang besar.read_csv()
mendeteksi kolom bertipe data tanggal dan
mengubahnya secara langsung.# Please type your code here
<- read_csv("data_input/youtubetrends.csv") vids
Penjelasan mengenai 16 kolom dalam dataframe:
trending_date
: tanggal trending (format: YY.MM.DD)title
: judul videochannel_title
: nama channel Youtubecategory_id
: kategori videopublish_time
: tanggal upload video (format:
YYYY-MM-DD-HH-MM-SS)views
: jumlah views dalam video tersebutlikes
: jumlah likes dalam video tersebutdislikes
: jumlah dislikes dalam video tersebutcomment_count
jumlah komentarcomment_disabled
: apakah kolom komentar tidak
diaktifkanrating_disabled
: apakah rating video tidak
diaktifkanvideo_error_or_removed
: apakah video dihapuspublish_hour
: jam video tersebut dipublishpublish_when
: range video tersebut dipublishpublish_wday
: hari video tersebut dipublishtimetotrend
: rentan waktu video tersebut dari dipublish
sampai menjadi trendingdplyr
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.
Official Documentation & Cheatsheet
dplyr
: https://dplyr.tidyverse.org/
Tugas: Kita sebagai tim data diminta untuk mengambil data
video youtube yang berisikan kolom trending_date
dan
title
saja.
Cara base:
# Please run the code down below
c("trending_date", "title")] vids[,
Cara dplyr:
Fungsi yang akan digunakan adalah select()
# Please type your code here
select(.data = vids, trending_date, title)
Tugas: Kita sebagai tim data diminta untuk mengambil data
video youtube yang kategorinya adalah Music
dan memiliki
views lebih dari 1 juta
.
Cara base:
# Please run the code down below
$category_id == "Music" & vids$views > 1000000,] vids[vids
Cara dplyr:
Fungsi yang akan digunakan adalah filter()
# Please type your code here
filter(.data = vids, category_id == "Music" & views > 1000000)
Tugas: Kita secara tiba-tiba diminta tolong oleh Mas Tria
mengenai hal yang urgent, yaitu untuk menarik data dengan kolom
title
, category_id
& likes
untuk video youtube dengan kategori Entertainment
&
Comedy
dengan likes lebih dari 50.000
# Please type your code here
<- select(.data = vids, title, category_id, likes)
vids_ec <- filter(.data = vids_ec, category_id %in% c("Entertainment", "Comedy") & likes > 5e4)
vids_ec
vids_ec
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
head(iris)
Deskripsi kolom:
Sepal.Length
: Panjang ukuran daunSepal.Width
: Lebar ukuran daunPetal.Length
: Panjang ukuran bungaPetal.Width
: Lebar ukuran bungaSpecies
: 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:
<- filter(.data = iris, Species == "setosa")
iris_setosa <- select(.data = iris_setosa, Sepal.Length, Species)
iris_setosa
iris_setosa
Hasil dengan piping:
%>%
iris filter(Species == "setosa") %>%
select(Sepal.Length, Species)
Shortcut Piping: CTRL/CMD + SHIFT + M
Inspeksi tipe data untuk membuktikan apakah fungsi
read_csv()
memang betul langsung mengubah tipe data yang
tanggal atau tidak, sekaligus kita akan mencoba untuk mengecek tipe data
apa saja yang belum sesuai.
Cara base:
# Please run the code down below
str(vids)
#> spec_tbl_df [2,986 × 16] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
#> $ trending_date : Date[1:2986], format: "2017-11-14" "2017-11-14" ...
#> $ title : chr [1:2986] "WE WANT TO TALK ABOUT OUR MARRIAGE" "The Trump Presidency: Last Week Tonight with John Oliver (HBO)" "Racist Superman | Rudy Mancuso, King Bach & Lele Pons" "Nickelback Lyrics: Real or Fake?" ...
#> $ channel_title : chr [1:2986] "CaseyNeistat" "LastWeekTonight" "Rudy Mancuso" "Good Mythical Morning" ...
#> $ category_id : chr [1:2986] "People and Blogs" "Entertainment" "Comedy" "Entertainment" ...
#> $ publish_time : POSIXct[1:2986], format: "2017-11-13 12:13:01" "2017-11-13 02:30:00" ...
#> $ views : num [1:2986] 748374 2418783 3191434 343168 2095731 ...
#> $ likes : num [1:2986] 57527 97185 146033 10172 132235 ...
#> $ dislikes : num [1:2986] 2966 6146 5339 666 1989 ...
#> $ comment_count : num [1:2986] 15954 12703 8181 2146 17518 ...
#> $ comments_disabled : logi [1:2986] FALSE FALSE FALSE FALSE FALSE FALSE ...
#> $ ratings_disabled : logi [1:2986] FALSE FALSE FALSE FALSE FALSE FALSE ...
#> $ video_error_or_removed: logi [1:2986] FALSE FALSE FALSE FALSE FALSE FALSE ...
#> $ publish_hour : num [1:2986] 12 2 14 6 13 14 0 16 9 8 ...
#> $ publish_when : chr [1:2986] "8am to 3pm" "12am to 8am" "8am to 3pm" "12am to 8am" ...
#> $ publish_wday : chr [1:2986] "Monday" "Monday" "Sunday" "Monday" ...
#> $ timetotrend : chr [1:2986] "1" "1" "2" "1" ...
#> - attr(*, "spec")=
#> .. cols(
#> .. trending_date = col_date(format = ""),
#> .. title = col_character(),
#> .. channel_title = col_character(),
#> .. category_id = col_character(),
#> .. publish_time = col_datetime(format = ""),
#> .. views = col_double(),
#> .. likes = col_double(),
#> .. dislikes = col_double(),
#> .. comment_count = col_double(),
#> .. comments_disabled = col_logical(),
#> .. ratings_disabled = col_logical(),
#> .. video_error_or_removed = col_logical(),
#> .. publish_hour = col_double(),
#> .. publish_when = col_character(),
#> .. publish_wday = col_character(),
#> .. timetotrend = col_character()
#> .. )
#> - attr(*, "problems")=<externalptr>
Cara dplyr:
Fungsi yang akan digunakan adalah glimpse()
# Please type your code here
glimpse(vids)
#> Rows: 2,986
#> Columns: 16
#> $ trending_date <date> 2017-11-14, 2017-11-14, 2017-11-14, 2017-11-14…
#> $ title <chr> "WE WANT TO TALK ABOUT OUR MARRIAGE", "The Trum…
#> $ channel_title <chr> "CaseyNeistat", "LastWeekTonight", "Rudy Mancus…
#> $ category_id <chr> "People and Blogs", "Entertainment", "Comedy", …
#> $ publish_time <dttm> 2017-11-13 12:13:01, 2017-11-13 02:30:00, 2017…
#> $ views <dbl> 748374, 2418783, 3191434, 343168, 2095731, 1191…
#> $ likes <dbl> 57527, 97185, 146033, 10172, 132235, 9763, 1599…
#> $ dislikes <dbl> 2966, 6146, 5339, 666, 1989, 511, 2445, 778, 11…
#> $ comment_count <dbl> 15954, 12703, 8181, 2146, 17518, 1434, 1970, 34…
#> $ comments_disabled <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE…
#> $ ratings_disabled <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE…
#> $ video_error_or_removed <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE…
#> $ publish_hour <dbl> 12, 2, 14, 6, 13, 14, 0, 16, 9, 8, 21, 22, 12, …
#> $ publish_when <chr> "8am to 3pm", "12am to 8am", "8am to 3pm", "12a…
#> $ publish_wday <chr> "Monday", "Monday", "Sunday", "Monday", "Sunday…
#> $ timetotrend <chr> "1", "1", "2", "1", "2", "1", "2", "2", "1", "1…
Kolom apa saja yang belum sesuai dari hasil inspeksi datanya?
Menjadi Tipe Data Factor
Menjadi Tipe Data Numeric
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
$category_id <- as.factor(vids$category_id) vids
Cara dplyr:
Fungsi yang akan digunakan adalah mutate()
# Please type your code here
<- vids %>%
vids_clean mutate(timetotrend = as.integer(timetotrend),
category_id = as.factor(category_id),
channel_title = as.factor(channel_title),
publish_hour = as.factor(publish_hour),
publish_when = as.factor(publish_when),
publish_wday = as.factor(publish_wday))
glimpse(vids_clean)
#> Rows: 2,986
#> Columns: 16
#> $ trending_date <date> 2017-11-14, 2017-11-14, 2017-11-14, 2017-11-14…
#> $ title <chr> "WE WANT TO TALK ABOUT OUR MARRIAGE", "The Trum…
#> $ channel_title <fct> "CaseyNeistat", "LastWeekTonight", "Rudy Mancus…
#> $ category_id <fct> People and Blogs, Entertainment, Comedy, Entert…
#> $ publish_time <dttm> 2017-11-13 12:13:01, 2017-11-13 02:30:00, 2017…
#> $ views <dbl> 748374, 2418783, 3191434, 343168, 2095731, 1191…
#> $ likes <dbl> 57527, 97185, 146033, 10172, 132235, 9763, 1599…
#> $ dislikes <dbl> 2966, 6146, 5339, 666, 1989, 511, 2445, 778, 11…
#> $ comment_count <dbl> 15954, 12703, 8181, 2146, 17518, 1434, 1970, 34…
#> $ comments_disabled <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE…
#> $ ratings_disabled <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE…
#> $ video_error_or_removed <lgl> FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE…
#> $ publish_hour <fct> 12, 2, 14, 6, 13, 14, 0, 16, 9, 8, 21, 22, 12, …
#> $ publish_when <fct> 8am to 3pm, 12am to 8am, 8am to 3pm, 12am to 8a…
#> $ publish_wday <fct> Monday, Monday, Sunday, Monday, Sunday, Monday,…
#> $ timetotrend <int> 1, 1, 2, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 2, 1,…
<- vids %>%
vids_mutate_if mutate(timetotrend = as.numeric(timetotrend)) %>%
mutate_if(is.numeric, as.factor)
<- vids %>%
vids_mutate_at mutate(timetotrend = as.numeric(timetotrend)) %>%
mutate_at(.vars = c("category_id", "channel_title", "publish_hour", "publish_when", "publish_wday"), .funs = as.factor)
Kita akan menambahkan beberapa kolom baru, yaitu:
likes_per_view
: likes per viewsdislikes_per_view
: dislikes per viewscomment_per_view
: comment_count per viewsCara base:
# Please run the code down below
$likesp <- vids$likes / vids$views vids
Cara dplyr:
Fungsi yang akan digunakan adalah mutate()
# Please type your code here
<- vids_clean %>%
vids_clean mutate(likes_per_view = likes/views,
dislikes_per_view = dislikes/views,
comment_per_view = comment_count/views)
Tugas: Ternyata pekerjaan kita masih belum selesai, kita diminta untuk menghitung rata-rata views video trending yang dimiliki oleh tiap channel YouTube
Cara base:
# Please run the code down below
aggregate(views ~ channel_title, data = vids_clean, FUN = mean)
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()
: menghitung nilai statistik tertentu.ungroup()
: melepaskan pengelompokkan agar proses apapun
setelahnya dilakukan untuk keseluruhan data.# Please type your code here
<- vids_clean %>%
vids_agg group_by(channel_title) %>%
summarise(views_average = mean(views)) %>%
ungroup()
vids_agg
Note: penggunaan
ungroup()
memang sering kali tidak terlihat efeknya, namun best practice setelah melakukan tahapan yang menggunakan grouping adalah melepas grouping tersebut menggunakan ungroup.
Sebagai contohnya, mari kita coba cari tahu periode (hari dan jam) kapan seorang YouTuber dengan kontek category Music mendapatkan rata-rata views terbanyak!
Tanpa ungroup():
# Please run the code down below
%>%
vids_clean filter(category_id == "Music") %>%
group_by(publish_wday, publish_when) %>%
summarise(mean_views = mean(views)) %>%
top_n(1)
Dengan ungroup():
# Please run the code down below
%>%
vids_clean filter(category_id == "Music") %>%
group_by(publish_wday, publish_when) %>%
summarise(mean_views = mean(views)) %>%
ungroup() %>%
top_n(1)
Tugas: Agar hasil agregasi untuk rata-rata views dari setiap
channel title dapat dilihat secara rapi, mari kita urutkan rata-rata
views dari objek vids_agg
dari yang paling tinggi ke paling
rendah.
Cara base:
# Please run the code down below
order(vids_agg$views_average, decreasing = T),] vids_agg[
Cara dplyr:
Fungsi yang akan digunakan adalah arrange()
# Please type your code here
%>%
vids_agg arrange(desc(views_average))
###️ Dive Deeper
Background: Tria saat ini adalah seorang Data Science Instructor di Algoritma. Tria ingin menjadi seorang YouTuber namun masih bingung terkait konten apa yang sebaiknya dibuat. Tria adalah seseorang yang ambisius karena ingin videonya sering masuk ke jajaran video trending.
vids_count
.Hint: Untuk melakukan perhitungan count, fungsi yang
digunakan adalah n()
# your code here
<- vids_clean %>%
vids_count group_by(category_id) %>%
summarise(count = n()) %>%
arrange(desc(count))
vids_count
Kategori dengan jumlah video trending terbanyak adalah …
<- vids_clean %>%
vids_top_channel filter(category_id == "Entertainment") %>%
group_by(channel_title) %>%
summarise(sum_views = sum(views)) %>%
arrange(desc(sum_views))
head(vids_top_channel, 10)
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.
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
:
ggplot()
ggplotly()
Business Question:
Buatlah analisis kategori video yang paling sering masuk ke dalam jajaran video trending!
# Please type your code here
vids_count
# Please type your code here
<- vids_count %>%
plot1 ggplot(aes(x = count,
y = reorder(category_id, count),
fill = count)) +
geom_col() +
scale_fill_gradient(low = "red", high = "black") +
theme_minimal() +
theme(legend.position = "none") +
labs(title = 'Trending Categories on Youtube US 2017' ,
x = 'Video Count',
y = NULL)
Fungsi yang akan digunakan ggplotly()
# Please type your code here
ggplotly(plot1)
Tooltip adalah informasi atau label yang ditampilkan ketika user meng-hover plot.
# install.packages("glue")
library(glue)
# contoh penggunaan fungsi glue dari library glue
<- c("Tria", "Fafil", "Kevin", "Lita", "Victor")
nama glue("Nama Instructor: {nama}")
#> Nama Instructor: Tria
#> Nama Instructor: Fafil
#> Nama Instructor: Kevin
#> Nama Instructor: Lita
#> Nama Instructor: Victor
Tahapan dalam menambahkan tooltip
:
glue()
digunakan untuk
menampilkan nilai pada kolom.# Please type your code here
<- vids_count %>%
vids_count mutate(label = glue("Category = {category_id}
Video Count = {count} Videos"))
text
pada aes()
# Please type your code here
<- vids_count %>%
plot1 ggplot(aes(x = count,
y = reorder(category_id, count),
fill = count,
text = label)) +
geom_col() +
scale_fill_gradient(low = "red", high = "black") +
theme_minimal() +
theme(legend.position = "none") +
labs(title = 'Trending Categories on Youtube US 2017' ,
x = 'Video Count',
y = NULL)
tooltip = "text"
pada
ggplotly()
# Please type your code here
ggplotly(plot1, tooltip = "text")
Business Question:
Dari kategori Entertainment, lakukan analisis top 10 channel YouTube dengan rata-rata jumlah views tertinggi!
library(scales)
# Please type your code here
<- vids_top_channel %>%
vids_top10_channel mutate(label = glue("Channel: {channel_title}
Sum Views: {scales::comma(sum_views)}")) %>%
head(10)
vids_top10_channel
# ggplot: lollipop plot
# geom_point() + geom_segment()
<- vids_top10_channel %>%
plot2 ggplot(aes(x = sum_views,
y = reorder(channel_title, sum_views),
color = sum_views,
text = label)) +
geom_segment(aes(x = 0, xend = sum_views, yend = channel_title), size = 1) +
geom_point(size = 3) +
labs(x = 'Total Views',
y = NULL,
title = 'Top 10 YouTube Channels in Entertainment') +
scale_color_gradient(low = "red", high = "black") +
scale_x_continuous(labels = scales::comma) +
theme_minimal() +
theme(legend.position = "none",
plot.margin = margin(r = 20))
# plotly
ggplotly(plot2, tooltip = "text")
Business Question:
Setelah menganalisis top 10 channel dari kategori video
Entertainment, kita ingin melihat aktivitas viewers pada kategori
tersebut di setiap publish_hour
. Tipe plot apa yang baiknya
digunakan? Buatlah interactive plotnya.
Tahapan dari data vids_clean
: - filter category_id yang
Entertainment - tabel agregasi: mean(views) untuk masing-masing
publish_hour - mutate (buat kolom baru) untuk tooltip
# data
<- vids_clean %>%
vids_trend filter(category_id == "Entertainment") %>%
group_by(publish_hour) %>%
summarise(mean_views = mean(views)) %>%
ungroup() %>% # opsional, karena grouping hanya 1 kolom
mutate(label = glue("Publish Hour: {publish_hour}
Average Views: {scales::comma(mean_views)}"))
# ggplot
<- vids_trend %>%
plot3 ggplot(aes(x = publish_hour, y = mean_views)) +
geom_area(group = 1, fill="red", alpha=0.4) +
geom_line(group = 1, color = "red") +
geom_point(aes(text = label)) +
scale_y_continuous(labels = scales::comma) +
labs(
title = "Viewers Activity for Entertainment Videos",
x = "Publish Hour",
y = "Average Views"
+
) theme_minimal()
# plotly
ggplotly(plot3, tooltip = "text")
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:
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:
::include_graphics(path = "assets/shiny architecture.png") knitr
# install.packages("shinydashboard")
library(shinydashboard)
Referensi:
shiny Cheatsheet
: https://raw.githubusercontent.com/rstudio/cheatsheets/main/shiny.pdfshiny Gallery
: https://shiny.rstudio.com/gallery/shiny Input
Gallery: https://shiny.rstudio.com/gallery/widget-gallery.htmlshinyWidgets
: http://shinyapps.dreamrs.fr/shinyWidgets/shinydashboard
: https://rstudio.github.io/shinydashboard/