Project ini adalah salah satu project yang terdapat di DQLab dan merupakan bagian dari proses pembelajaran saya di platform DQLab. DQLab adalah salah satu platform kursus data science di Indonesia. Mentor dalam project ini adalah Mr. Farkhan Novianto, seorang Head of Data Analytics di AMARTHA.
Website DQLab: https://academy.dqlab.id/
DQLab Finance merupakan perusahaan finance yang sudah mempunyai banyak cabang tersebar dimana-mana. Sejak berdiri pada Januari 2020, DQLab Finance konsisten menyalurkan pembiayaan untuk masyarakat dan semakin berkembang setiap bulannya dengan membuka cabang baru.
Walaupun berumur kurang dari 1 tahun, DQLab Finance sudah mempunyai banyak cabang, oleh karena itu perlu dipantau bagaimana performa dari cabang - cabang tersebut.
Pada masing-masing cabang, terdapat agen-agen yang bertugas mencari dan mendata calon mitra yang akan mengajukan pinjaman kepada DQLab Finance. Lalu jika sudah disetujui, agen juga yang akan memberikan uang tersebut kepada mitra.
Sebagai seorang data analyst, kamu diminta untuk menganalisis performa dari cabang-cabang yang ada di DQLab Finance.
Pada tugas kali ini, kamu akan menganalisis bagaimana performa cabang pada bulan lalu, yakni Mei 2020.
Langkah yang akan dilakukan adalah,
Memfilter data untuk bulan Mei 2020
Membuat summary per cabang untuk melihat data 5 cabang terbaik dan terburuk
Karena cabang bertambah setiap bulannya, maka perlu dicek umur cabang dan performa mei
Mencari cabang terburuk untuk masing - masing kelompok umur
Pada analisis kali ini, akan digunakan beberapa package yang membantu kita dalam melakukan analisis data,
mutate() membuat variabel baru berdasarkan variabel yang ada
select() memilih variabel berdasarkan namannya
filter() memfilter data berdasarkan value dari variabel
summarise() mengubah beberapa nilai menjadi satu ringkasan nilai
arrange() mengurutkan baris data
ggplot(data) + geom_type(aes(x,y,fill,color))
geom_type diganti dengan fungsi sesuai dengan jenis plot yang diharapkan, misalnya geom_line, geom_bar, geom_point, geom_boxplot dan lainnya.
comma() mengubah numerik menjadi ada simbol ribuan, misalnya 10000000000 diubah menjadi 10,000,000,000
percent() mengubah numerik menjadi ada format persen, misalnya 0.65877 diubah menjadi 66%
Untuk Dataset yang digunakan sudah disediakan dalam format rds sehingga bisa langsung dibaca di R dengan cara :
df_loan <- read.csv(‘https://storage.googleapis.com/dqlab-dataset/loan_disbursement.csv’, stringsAsFactors = F)
Membaca dan melihat isi data
df_loan <- read.csv('https://storage.googleapis.com/dqlab-dataset/loan_disbursement.csv', stringsAsFactors = F)
dplyr::glimpse(df_loan)
## Rows: 9,754
## Columns: 5
## $ loan_id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17…
## $ tanggal_cair <chr> "2020-01-06", "2020-01-06", "2020-01-06", "2020-01-06", "…
## $ cabang <chr> "AA", "AA", "AA", "AA", "AA", "AA", "AB", "AB", "AB", "AB…
## $ agen <chr> "AA-1", "AA-1", "AA-1", "AA-2", "AA-2", "AA-2", "AB-1", "…
## $ amount <int> 320000, 440000, 200000, 430000, 360000, 220000, 320000, 4…
Terlihat bahwa ada 9,754 baris data (Observations) dan ada 5 kolom (Variables), berikut penjelasannya :
loan_id : unik ID dari data ini
tanggal_cair : tanggal uang diberikan kepada mitra
cabang : lokasi agen bekerja dan tempat mitra terdaftar
agen : petugas lapangan yang melakukan pencairan
amount : jumlah uang yang dicairkan
Untuk melihat data bulan Mei 2020, gunakan fungsi filter untuk memfilter data df_loan untuk tanggal dari awal mei ‘2020-05-01’ sampai dengan akhir mei ‘2020-05-31’.
Lalu hitung total_amount untuk masing - masing cabang menggunakan group_by dan summarise kemudian simpan hasilnya menjadi df_loan_mei.
Lalu gunakan pipe %>% untuk menyambungkan fungsi.
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
df_loan_mei <- df_loan %>%
filter(tanggal_cair >= '2020-05-01', tanggal_cair <= '2020-05-31') %>%
group_by(cabang) %>%
summarise(total_amount = sum(amount))
df_loan_mei
## # A tibble: 22 × 2
## cabang total_amount
## <chr> <int>
## 1 AA 75710000
## 2 AB 81440000
## 3 AC 83990000
## 4 AD 76080000
## 5 AE 54200000
## 6 AF 68040000
## 7 AG 74080000
## 8 AH 73840000
## 9 AI 46640000
## 10 AJ 43580000
## # … with 12 more rows
Tampilkan 5 cabang terbesar dari data df_loan_mei, urutkan dengan fungsi arrange, pakai desc untuk mengurutkan dari yang paling besar. tampilkan 5 data teratas menggunakan fungsi head.
Gunakan fungsi comma dari package scales untuk menampilkan total_amount agar lebih mudah dibandingkan.
Jangan lupa gunakan pipe %>% untuk menyambungkan fungsi.
library(dplyr)
library(scales)
df_loan_mei %>%
arrange(desc(total_amount)) %>%
mutate(total_amount = comma(total_amount)) %>%
head(5)
## # A tibble: 5 × 2
## cabang total_amount
## <chr> <chr>
## 1 AC 83,990,000
## 2 AB 81,440,000
## 3 AD 76,080,000
## 4 AA 75,710,000
## 5 AG 74,080,000
Tampilkan 5 cabang terbesar dari data df_loan_mei, urutkan dengan fungsi arrange dari yang paling kecil tampilkan 5 data teratas menggunakan fungsi head.
Gunakan fungsi comma dari package scales untuk menampilkan total_amount agar lebih mudah dibandingkan.
Jangan lupa gunakan pipe %>% untuk menyambungkan fungsi.
library(dplyr)
library(scales)
df_loan_mei %>%
arrange(total_amount) %>%
mutate(total_amount = comma(total_amount)) %>%
head(5)
## # A tibble: 5 × 2
## cabang total_amount
## <chr> <chr>
## 1 AV 30,280,000
## 2 AS 31,740,000
## 3 AT 34,840,000
## 4 AU 35,610,000
## 5 AO 39,120,000
Terjadi perbedaan yang sangat signifikan antara top 5 dengan bottom 5. Hal ini mungkin karena umur cabang yang berbeda beda karena ada pertumbuhan cabang baru setiap bulannya.
Selanjutnya perlu dicek apakah ada perbedaan total amount untuk umur cabang yang berbeda - beda
Karena tidak tersedia data umur cabang, maka perlu dihitung terlebih dahulu, yakni dengan menghitung sudah berapa lama sejak tanggal cair pertama sampai dengan bulan Mei.
Gunakan data df_loan yang berisi semua tanggal_cair dari awal lalu cari tanggal_cair pertama kali per cabang dan simpan sebagai pertama_cair.
Untuk memudahkan cara perhitungan umur dengan membagi jumlah selisih hari dengan 30, karena itu tanggal batas nya menggunakan tanggal tengah bulan (2020-05-15), agar tidak terlalu mempengaruhi presisi perhitungan.
Jangan lupa gunakan pipe %>% untuk menyambungkan fungsi.
library(dplyr)
df_cabang_umur <- df_loan %>%
group_by(cabang) %>%
summarise(pertama_cair = min(tanggal_cair)) %>%
mutate(umur = as.numeric(as.Date('2020-05-15') - as.Date(pertama_cair)) %/% 30)
df_cabang_umur
## # A tibble: 22 × 3
## cabang pertama_cair umur
## <chr> <chr> <dbl>
## 1 AA 2020-01-06 4
## 2 AB 2020-01-06 4
## 3 AC 2020-01-06 4
## 4 AD 2020-01-06 4
## 5 AE 2020-02-03 3
## 6 AF 2020-02-03 3
## 7 AG 2020-02-03 3
## 8 AH 2020-02-03 3
## 9 AI 2020-03-02 2
## 10 AJ 2020-03-02 2
## # … with 12 more rows
Selanjutnya untuk membandingkan data umur dan performa di bulan mei, terlebih dahulu perlu digabungkan dulu data-data yang sudah dibuat sebelumnya dengan menggunakan fungsi inner_join, lalu simpan sebagai df_loan_mei_umur.
Jangan lupa gunakan pipe %>% untuk menyambungkan fungsi.
library(dplyr)
df_loan_mei_umur <- df_cabang_umur %>%
inner_join(df_loan_mei, by = 'cabang')
df_loan_mei_umur
## # A tibble: 22 × 4
## cabang pertama_cair umur total_amount
## <chr> <chr> <dbl> <int>
## 1 AA 2020-01-06 4 75710000
## 2 AB 2020-01-06 4 81440000
## 3 AC 2020-01-06 4 83990000
## 4 AD 2020-01-06 4 76080000
## 5 AE 2020-02-03 3 54200000
## 6 AF 2020-02-03 3 68040000
## 7 AG 2020-02-03 3 74080000
## 8 AH 2020-02-03 3 73840000
## 9 AI 2020-03-02 2 46640000
## 10 AJ 2020-03-02 2 43580000
## # … with 12 more rows
Untuk membuat plot, akan digunakan package ggplot2 agar script yang digunakan lebih konsisten ketika nanti ada perubahan dan supaya bisa lebih bisa dicustomisasi nantinya.
Gunakan data df_loan_mei_umur yang sudah dibuat sebelumnya.
library(ggplot2)
ggplot(df_loan_mei_umur, aes(x = umur, y = total_amount)) +
geom_point() +
scale_y_continuous(labels = scales::comma) +
labs(title = "Semakin berumur, perfoma cabang akan semakin baik",
x = "Umur (bulan)",
y = "Total Amount")
Terlihat bahwa ada pola semakin tua cabang, maka performa nya semakin baik.
Hal ini karena cabang tersebut masih berkembang sehingga belum sampai pada performa maksimal.
Akan tetapi pada masing - masing umur itu juga ada cabang yang performanya dibawah yang lain.
Selanjutnya akan dianalisis cabang yang performanya lebih rendah dari yang lain pada umur yang sama
Selanjutnya Untuk mencari cabang yang performanya rendah pada setiap kelompok umur, akan digunakan nilai Quartile dan Inter Quartile Range dari setiap umur.
Dikatakan rendah jika performanya kurang dari (Q1 - IQR).
Untuk itu perlu dicari dulu nilai Q1, Q3 dan IQR untuk setiap umur dengan menggunakan data df_loan_mei_umur. Untuk membuat variabel ini, gunakan group_by dan mutate karena variabel ini akan digunakan lagi oleh semua data.
Setelah itu buat variabel baru flag yang akan berisi ‘rendah’ jika performanya kurang dari (Q1 - IQR) dan ‘baik’ untuk selain itu dan simpan hasilnya sebagai df_loan_mei_flag.
Lalu filter df_loan_mei_flag hanya untuk flag rendah, agar terlihat cabang mana saja yang masuk kelompok ini, dan ubah kolom numeric menjadi comma dengan fungsi mutate_if
Jangan lupa gunakan pipe %>% untuk menyambungkan fungsi.
library(dplyr)
library(scales)
df_loan_mei_flag <- df_loan_mei_umur %>%
group_by(umur) %>%
mutate(Q1 = quantile(total_amount, 0.25),
Q3 = quantile(total_amount, 0.75),
IQR = (Q3-Q1)) %>%
mutate(flag = ifelse(total_amount < (Q1 - IQR), 'rendah','baik'))
df_loan_mei_flag %>%
filter(flag == 'rendah') %>%
mutate_if(is.numeric, funs(comma))
## `mutate_if()` ignored the following grouping variables:
## • Column `umur`
## Warning: `funs()` was deprecated in dplyr 0.8.0.
## Please use a list of either functions or lambdas:
##
## # Simple named list:
## list(mean = mean, median = median)
##
## # Auto named with `tibble::lst()`:
## tibble::lst(mean, median)
##
## # Using lambdas
## list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.
## # A tibble: 2 × 8
## # Groups: umur [2]
## cabang pertama_cair umur total_amount Q1 Q3 IQR flag
## <chr> <chr> <dbl> <chr> <chr> <chr> <chr> <chr>
## 1 AE 2020-02-03 3 54,200,000 64,580,000 73,900,000 9,320,000 rendah
## 2 AL 2020-03-02 2 40,650,000 43,580,000 44,590,000 1,010,000 rendah
Untuk memperjelas bagaimana performa cabang yang rendah ini, plot lagi seperti sebelumnya. Sekarang menggunakan data yang baru, yakni df_loan_mei_flag.
Lalu beri warna biru untuk cabang dengan flag ‘baik’ dan merah untuk yang ‘rendah’.
library(ggplot2)
ggplot(df_loan_mei_flag, aes(x = umur, y = total_amount)) +
geom_point(aes(color = flag)) +
scale_color_manual(breaks = c("baik", "rendah"),
values=c("blue", "red")) +
scale_y_continuous(labels = scales::comma) +
labs(title = "Ada cabang berpeforma rendah padahal tidak termasuk bottom 5 nasional",
color = "",
x = "Umur(bulan)",
y = "Total Amount")
Selanjutnya akan dianalisis lebih lanjut kenapa cabang itu bisa performanya rendah di mei
Untuk kali ini akan dilihat hanya untuk yang umur 3 bulan saja, dilihat detail performa pada bulan mei dengan mengihitung,
jumlah hari pencairan dalam 1 bulan,
jumlah agen yang aktif,
total loan yang cair,
rata - rata amount cair per loan.
dan ubah kolom numeric menjadi comma dengan fungsi mutate_if
Jangan lupa gunakan pipe %>% untuk menyambungkan fungsi.
library(dplyr)
library(scales)
df_loan_mei_flag %>%
filter(umur == 3) %>%
inner_join(df_loan, by = 'cabang') %>%
filter(tanggal_cair >= '2020-05-01', tanggal_cair <= '2020-05-31') %>%
group_by(cabang, flag) %>%
summarise(jumlah_hari = n_distinct(tanggal_cair),
agen_aktif = n_distinct(agen),
total_loan_cair = n_distinct(loan_id),
avg_amount = mean(amount),
total_amount = sum(amount)) %>%
arrange(total_amount) %>%
mutate_if(is.numeric, funs(comma))
## `summarise()` has grouped output by 'cabang'. You can override using the
## `.groups` argument.
## `mutate_if()` ignored the following grouping variables:
## # A tibble: 4 × 7
## # Groups: cabang [4]
## cabang flag jumlah_hari agen_aktif total_loan_cair avg_amount total_amount
## <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 AE rendah 21 3 175 309,714 54,200,000
## 2 AF baik 21 3 225 302,400 68,040,000
## 3 AH baik 21 3 241 306,390 73,840,000
## 4 AG baik 21 3 241 307,386 74,080,000
Dari hasil eksplorasi sebelumnya, terlihat bahwa yang berbeda jauh hanya total_loan_cair saja. Jumlah hari dan jumlah agen dalam 1 bulan sama semua.
Selanjutnya perlu dilihat bagaimana perbandingan nya per agent.
Untuk melanjutkan tadi, dilihat untuk yang umur 3 bulan dan flag nya rendah dilihat detail performa pada bulan mei per agen dengan mengihitung,
jumlah hari pencairan dalam 1 bulan,
total loan yang cair,
rata - rata amount cair per loan
total amount cair
dan ubah kolom numeric menjadi comma dengan fungsi mutate_if
Jangan lupa gunakan pipe %>% untuk menyambungkan fungsi.
library(dplyr)
library(scales)
df_loan_mei_flag %>%
filter(umur == 3, flag == 'rendah') %>%
inner_join(df_loan, by = 'cabang') %>%
filter(tanggal_cair >= '2020-05-01', tanggal_cair <= '2020-05-31') %>%
group_by(cabang, agen) %>%
summarise(jumlah_hari = n_distinct(tanggal_cair),
total_loan_cair = n_distinct(loan_id),
avg_amount = mean(amount),
total_amount = sum(amount)) %>%
arrange(total_amount) %>%
mutate_if(is.numeric, funs(comma))
## `summarise()` has grouped output by 'cabang'. You can override using the
## `.groups` argument.
## `mutate_if()` ignored the following grouping variables:
## # A tibble: 3 × 6
## # Groups: cabang [1]
## cabang agen jumlah_hari total_loan_cair avg_amount total_amount
## <chr> <chr> <chr> <chr> <chr> <chr>
## 1 AE AE-3 4 16 310,625 4,970,000
## 2 AE AE-2 18 73 320,274 23,380,000
## 3 AE AE-1 21 86 300,581 25,850,000
Pada tabel sebelumnya, terlihat pula bahwa ada cabang yang punya 3 agen, tapi performa nya jauh diatas cabang AE, bahkan yang paling tinggil diantara cabang lain pada umur tersebut, lebih tinggi dari yang mempunya 4 agen cabang tersebut adalah cabang AH.
Dengan cara yang hampir sama, akan dilihat bagaimana performa masing-masing agen dari cabang AH tersebut. Hanya saja untuk ini bisa langsung pakai data df_loan lalu filter nama cabang nya saja.
library(dplyr)
library(scales)
df_loan %>%
filter(cabang == 'AH') %>%
filter(tanggal_cair >= '2020-05-01', tanggal_cair <= '2020-05-31') %>%
group_by(cabang, agen) %>%
summarise(jumlah_hari = n_distinct(tanggal_cair),
total_loan_cair = n_distinct(loan_id),
avg_amount = mean(amount),
total_amount = sum(amount)) %>%
arrange(total_amount) %>%
mutate_if(is.numeric, funs(comma))
## `summarise()` has grouped output by 'cabang'. You can override using the
## `.groups` argument.
## `mutate_if()` ignored the following grouping variables:
## # A tibble: 3 × 6
## # Groups: cabang [1]
## cabang agen jumlah_hari total_loan_cair avg_amount total_amount
## <chr> <chr> <chr> <chr> <chr> <chr>
## 1 AH AH-3 19 74 303,649 22,470,000
## 2 AH AH-1 21 81 301,358 24,410,000
## 3 AH AH-2 21 86 313,488 26,960,000
Berdasarkan analisis tersebut, dapat disimpulkan bahwa rendahnya performa dari cabang AE adalah karena salah satu agen yang melakukan pencairan hanya 4 hari dalam 1 bulan, padahal agen lain bisa aktif 21 hari.
Hal ini membuat total amount dari agen tersebut hanya 20% dibandingkan agen yang lainnya.
Sedangkan pada cabang AH, performanya sangat baik karena ketiga agen melakukan pencairan hampir / selalu setiap hari kerja. 2 orang full 21 hari 1 orang 19 hari. Sehingga performa nya terjaga dengan baik.
Perlu diperhatikan juga bahwa untuk membandingkan performa cabang itu sebaiknya di kelompokkan dulu berdasarkan karakteristik yang sama. Tidak langsung semua cabang dibandingkan tanpa mengetahui karakteristik nya.
Apalagi ketika dalam real world nanti cabang ini bisa terletak di berbeda wilayah (pulau misalnya) yang mempunyai kultur yang berbeda
Selanjutnya perlu dianalisis lebih lanjut kenapa ada agen yang hanya aktif beberapa hari saja dalam sebulan.
Untuk kedepannya setiap agen agar dipastikan untuk bisa aktif setiap hari nya, sehingga bisa menjaga performa cabang.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Tentang saya, silakan kunjungi: